更新/注意:
我想我可能要找的是用
参考:PCRE regular expressions using named pattern subroutines.
(请仔细阅读:)
我有一个字符串,它包含可变数量的段(简化):
$subject = 'AA BB DD '; // could be 'AA BB DD CC EE ' as well
我现在想要匹配这些片段,并通过matches数组返回它们:
$pattern = '/^(([a-z]+) )+$/i';
$result = preg_match_all($pattern, $subject, $matches);
这将只返回捕获组2的最后一个匹配项:DD
。
有没有办法在一次正则表达式执行中检索所有子模式捕获(AA
、BB
、DD
)?难道preg_match_all
不适合这个吗?
这个问题是一个泛化。
$subject
和$pattern
都得到了简化。自然有了这样的通用列表AA
,BB
,..使用其他函数(例如explode
)或$pattern
的变体更容易提取。
但我特别问的是,如何使用preg_...
-family of functions返回所有的子组匹配。
对于现实生活中的情况,假设您有多个(嵌套的)不同数量的子模式匹配。
示例
这是一个用伪代码描述背景的例子。想象一下:
令牌的常规定义:
CHARS := [a-z]+
PUNCT := [.,!?]
WS := [ ]
基于这些对$subject
get进行标记化。标记化存储在一个标记数组中(type,offset,...)。
然后将该数组转换为字符串,每个令牌包含一个字符:
CHARS -> "c"
PUNCT -> "p"
WS -> "s"
因此,现在可以基于标记(而不是字符类等)运行正则表达式。在令牌流字符串索引上。例如。
regex: (cs)?cp
用标点符号表示一组或多组字符。
由于我现在可以将自定义的标记表示为正则表达式,因此下一步是构建语法。这只是一个例子,这是一种ABNF风格:
words = word | (word space)+ word
word = CHARS+
space = WS
punctuation = PUNCT
如果我现在将单词的语法编译成一个(标记)正则表达式,我希望自然地得到每个单词的所有子组匹配。
words = (CHARS+) | ( (CHARS+) WS )+ (CHARS+) # words resolved to tokens
words = (c+)|((c+)s)+c+ # words resolved to regex
我可以在这一点之前编写代码。然后我遇到了一个问题,子组匹配确实只包含他们的最后一个匹配。
因此,我可以选择自己为语法创建一个自动机(我想阻止它,以保持语法表达式的通用性),或者以某种方式使preg_match为我工作,这样我就可以节省时间。
基本上就是这样。也许现在可以理解为什么我简化了这个问题。
相关信息:
发布于 2014-06-18 01:23:58
类似的主题:Get repeated matches with preg_match_all()
检查选择的答案加上我的答案可能有用,我将在这里重复一遍:
来自http://www.php.net/manual/en/regexp.reference.repetition.php:
重复捕获子模式时,捕获的值是与最终迭代匹配的子字符串。
我个人放弃了,我会分两步来做。
编辑
我在另一个线程中看到了someone声称lookbehind方法能够做到这一点。
发布于 2011-06-16 19:51:30
试试这个:
preg_match_all("'[^ ]+'i",$text,$n);
$n[0]
将包含文本中所有非空格字符组的数组。
编辑:带有子组的:
preg_match_all("'([^ ]+)'i",$text,$n);
现在,$n[1]
将包含与$n[0]
完全相同的子组匹配。这实际上是毫无意义的。
Edit2:嵌套子组示例:
$test = "Hello I'm Joe! Hi I'm Jane!";
preg_match_all("/(H(ello|i)) I'm (.*?)!/i",$test,$n);
结果是:
Array
(
[0] => Array
(
[0] => Hello I'm Joe!
[1] => Hi I'm Jane!
)
[1] => Array
(
[0] => Hello
[1] => Hi
)
[2] => Array
(
[0] => ello
[1] => i
)
[3] => Array
(
[0] => Joe
[1] => Jane
)
)
发布于 2011-06-17 02:25:15
有没有一种方法可以用一次正则表达式执行来检索所有的匹配(AA,BB,DD)?preg_match_all不是不适合这样做吗?
您当前的正则表达式似乎用于preg_match()调用。试着这样做:
$pattern = '/[a-z]+/i';
$result = preg_match_all($pattern, $subject, $matches);
根据评论,我提到的ruby正则表达式:
sentence = %r{
(?<subject> cat | dog ){0}
(?<verb> eats | drinks ){0}
(?<object> water | bones ){0}
(?<adjective> big | smelly ){0}
(?<obj_adj> (\g<adjective>\s)? ){0}
The\s\g<obj_adj>\g<subject>\s\g<verb>\s\g<opt_adj>\g<object>
}x
md = sentence.match("The cat drinks water");
md = sentence.match("The big dog eats smelly bones");
但是我认为你需要一个词法分析器/解析器/记号赋予器在PHP中做同样的事情。:-|
https://stackoverflow.com/questions/6371226
复制相似问题