尽管我对伪代码中的正则表达式有足够的了解,但我在翻译我想要在 php regex perl 中做的事情时遇到了麻烦。
我正在尝试使用 preg_match 来提取我的部分表达式。
我有以下字符串${classA.methodA.methodB(classB.methodC(classB.methodD)))}
,我需要做两件事:
一种。验证语法
${classA.methodA.methodB(classB.methodC(classB.methodD)))}
有效的${classA.methodA.methodB}
有效的${classA.methodA.methodB()}
无效${methodB(methodC(classB.methodD)))}
无效
湾。我需要提取那些信息
${classA.methodA.methodB(classB.methodC(classB.methodD)))}
应该返回
1.classA
2.methodA
3.methodB(classB.methodC(classB.methodD)))
我已经创建了这段代码
$expression = '${myvalue.fdsfs.fsdf.blo(fsdf.fsfds(fsfs.fs))}';
$pattern = '/\$\{(?:([a-zA-Z0-9]+)\.)(?:([a-zA-Z\d]+)\.)*([a-zA-Z\d.()]+)\}/';
if(preg_match($pattern, $expression, $matches))
{
echo 'found'.'<br/>';
for($i = 0; $i < count($matches); $i++)
echo $i." ".$matches[$i].'<br/>';
}
结果是:
找到
0 ${myvalue.fdsfs.fsdf.blo(fsdf.fsfds(fsfs.fs))}
1 myvalue
2 fsdf
3 blo(fsdf.fsfds(fsfs.fs))
显然我很难提取重复的方法,并且它没有正确验证它(老实说,一旦我解决了另一个问题,我就把它留到最后了)所以允许使用空括号,并且它不会检查是否打开括号它必须关闭。
谢谢大家
更新
X m.buettner
谢谢你的帮助。我对您的代码进行了快速尝试,但它给出了一个非常小的问题,尽管我可以绕过它。问题与我没有在此处发布的先前代码之一相同,这是我尝试此字符串时:
$expression = '${myvalue.fdsfs}';
使用您的模式定义,它显示:
found
0 ${myvalue.fdsfs}
1 myvalue.fdsfs
2 myvalue
3
4 fdsfs
如您所见,第三行被捕获为不存在的空白。我不明白它为什么这样做,所以你能建议我如何或者我必须忍受它,因为 php regex 限制?
那就是说我只能告诉你谢谢。您不仅回答了我的问题,而且还尝试输入尽可能多的信息,并提供了许多关于开发模式时应遵循的正确路径的建议。
最后一件事我(愚蠢)忘记添加一个小重要案例,即多个参数除以逗号,所以
$expression = '${classA.methodAA(classB.methodBA(classC.methodCA),classC.methodCB)}';
$expression = '${classA.methodAA(classB.methodBA(classC.methodCA),classC.methodCB,classD.mehtodDA)}';
必须有效。
我对此进行了编辑
$expressionPattern =
'/
^ # beginning of the string
[$][{] # literal ${
( # group 1, used for recursion
( # group 2 (class name)
[a-z\d]+ # one or more alphanumeric characters
) # end of group 2 (class name)
[.] # literal .
( # group 3 (all intermediate method names)
(?: # non-capturing group that matches a single method name
[a-z\d]+ # one or more alphanumeric characters
[.] # literal .
)* # end of method name, repeat 0 or more times
) # end of group 3 (intermediate method names);
( # group 4 (final method name and arguments)
[a-z\d]+ # one or or more alphanumeric characters
(?: # non-capturing group for arguments
[(] # literal (
(?1) # recursively apply the pattern inside group 1
(?: # non-capturing group for multiple arguments
[,] # literal ,
(?1) # recursively apply the pattern inside group 1 on parameters
)* # end of multiple arguments group; repeat 0 or more times
[)] # literal )
)? # end of argument-group; make optional
) # end of group 4 (method name and arguments)
) # end of group 1 (recursion group)
[}] # literal }
$ # end of the string
/ix';
X Casimir et Hippolyte
您的建议也很好,但它暗示使用此代码时会出现一些复杂的情况。我的意思是代码本身很容易理解,但它变得不那么灵活。也就是说,它也给了我很多信息,这些信息肯定会在未来有所帮助。
X 异形
感谢您的支持,但是当我尝试此操作时,您的代码会下降:
$sourcestring='${classA1.methodA0.methodA1.methodB1(classB.methodC(classB.methodD))}';
结果是:
Array
( [0] => 数组 ( [0] => ${classA1.methodA0.methodA1.methodB1(classB.methodC(classB.methodD))} )
[1] => Array
(
[0] => classA1
)
[2] => Array
(
[0] => methodA0
)
[3] => Array
(
[0] => methodA1.methodB1(classB.methodC(classB.methodD))
)
)
它应该是
[2] => Array
(
[0] => methodA0.methodA1
)
[3] => Array
(
[0] => methodB1(classB.methodC(classB.methodD))
)
)
或者
[2] => Array
(
[0] => methodA0
)
[3] => Array
(
[0] => methodA1
)
[4] => Array
(
[0] => methodB1(classB.methodC(classB.methodD))
)
)