PHP preg_match_all,检查和分割

5

我想检查并分解这个字符串:

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

to:

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

我做了下面的正则表达式:
/{\$(?P<var_name>[^#]+)#(?P<module_name>[^\/]+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+))?)?)?)?)?}/

但它太丑了,而且只支持最多五个参数。请帮我编写递归部分以提取所有参数。

附注:是的,我可以将其拆分为var_namemodule_nameparamters三个部分,然后通过“/”来分割parameters部分,但我不喜欢这样做。

2个回答

3

你可以使用preg_split()

正则表达式:

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

丢弃数组中的第一个和第三个元素。

ideone演示



编辑:根据OP在评论中指定的新条件(而不是问题),它应该验证语法^\{\$\w+#\w+(?:/\w*)$并独立地将其标记为varmoduleparameters

正则表达式:

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

代码:

// https://dev59.com/cY_ea4cB1Zd3GeqPTNCz

$pattern = '@\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*+@';
$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);
}

输出:

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

ideone演示


正确,但还没有验证它。 - Varteresz Gabor
请在您的问题中具体说明需要进行验证的内容。 - Mariano
{$var_name#module_name} - 这种格式是必须的。参数是可选的:{$var_name#module_name/arg1/arg2/.../argN}。所有名称和值(变量名、模块名、参数)都可以通过 \w+进行检查。 - Varteresz Gabor
没问题,但是在这种方法中,我可以使用模式{\$(\w+)#(\w+)(?:\/([\w|\/]+))?},它已经被验证过了,下一步我可以通过/来分解$match[3]。但是我太有强迫症了。 :) - Varteresz Gabor
谢谢,抱歉有不准确的地方(如果我的英语不好的话)。 - Varteresz Gabor

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

你可以直接匹配并获取 groups。请看演示。 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);

  1. 太好了,谢谢。我将使用 {\$([^#]+)#([^\/]+)|\G(?!^)(\/[^\/]+)},因为需要 var_name ($1) 和 module_name ($2)。 2/a) matches[3] 从1开始索引。为什么? 2/b) 这个 \G(?!^) 是什么?我无法在谷歌上找到它。 :(
- Varteresz Gabor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接