2015-10-06 12 views
5

Tôi muốn kiểm tra 'n' nổ tung chuỗi này:PHP preg_match_all, kiểm tra & nổ

{$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/.../fooN} 

tới:

var_name[0] => 'gallery', 
modul_name[0] => 'pager', 
3[0] => 'collectionName', 
4[0] => 'imageName', 
5[0] => 'manual' 
... 
N[0] => 'fooN' 

tôi đã regexp sau:

/{\$(?P<var_name>[^#]+)#(?P<module_name>[^\/]+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+))?)?)?)?)?}/ 

, nhưng nó quá xấu và chỉ hỗ trợ tối đa năm tham số. Hãy giúp tôi tạo một phần đệ quy để trích xuất tất cả các tham số.

ps: Vâng, tôi có thể chia nhỏ này để var_name, module_nameparamters phần, sau đó tôi có thể phát nổ thông số phần bởi '/', nhưng tôi không thích nó.

Trả lời

3

Bạn có thể sử dụng preg_split().

Regex:

preg_split('@([$#])|[{}/][email protected]', $text) 

Và loại bỏ các mục đầu tiên và thứ ba trong mảng.

ideone Demo



EDIT: Để phản ánh điều kiện mới theo quy định của OP trong ý kiến ​​(không có trong câu hỏi): Cần xác cú pháp ^\{\$\w+#\w+(?:/\w*)$ và tokenize trong var, mô-đunthông số độc lập.

Regex:

~\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*+~ 

Code:

// http://stackoverflow.com/q/32969465/5290909 

$pattern = '@\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*[email protected]'; 
$text = '{$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/fooN}'; 

$result = preg_match_all($pattern, $text, $matches); 

if ($result === 0) { 
    // is invalid, does not match '~^\{\$\w+#\w+(?:/\w*)+$~' 
    echo "Invalid text"; 
} else { 
    // Assign vars (only to clarify) 
    $module_name = array_pop($matches)[0]; 
    $var_name = array_pop($matches)[0]; 
    $parameters = $matches; 

    echo "VAR NAME: \t'$var_name'\nMODULE: \t'$module_name'\nPARAMETERS:\n"; 
    print_r($matches); 
} 

Output:

VAR NAME: 'gallery' 
MODULE:  'pager' 
PARAMETERS: 
Array 
(
    [0] => collectionName 
    [1] => imageName 
    [2] => manual 
    [3] => no_effect 
    [4] => foo1 
    [5] => foo2 
    [6] => fooN 
) 

ideone Demo

+0

Phải, nhưng không xác nhận nó –

+0

Vui lòng chỉ định chính xác những gì cần được xác nhận trong câu hỏi của bạn – Mariano

+0

'{$ var_name # module_name}' - định dạng này được yêu cầu. Các đối số là tùy chọn: '{$ var_name # module_name/arg1/arg2 /.../ argN} 'Tất cả tên và giá trị (tên var, tên mô-đun, đối số) đều có thể kiểm tra bởi \ w +. –

2
{\$([^#]+)#|\G(?!^)([^\/]+)\/|\G(?!^)(.*?)}$ 

Bạn có thể chỉ cần thực hiện đối sánh thay thế và lấy groups .Xem demo.

https://regex101.com/r/cJ6zQ3/18

$re = "/{\\$([^#]+)#|\\G(?!^)([^\\/]+)\\/|\\G(?!^)(.*?)}$/m"; 
$str = "{\$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/.../fooN}"; 

preg_match_all($re, $str, $matches); 
+0

1) Siêu, thx. Tôi sẽ sử dụng '{\ $ ([^ #] +) # ([^ \ /] +) | \ G (?! ^) (\/[^ \ /] +)}', Vì var_name ($ 1) và module_name ($ 2) là bắt buộc. 2/a) khớp với [3] được lập chỉ mục từ 1. Tại sao? 2/b) đây là gì \ G (?! ^)? Tôi không thể google này. :( –