更新/注意:
我认为我可能正在寻找的是在PHP中获取captures of a group。
参考:PCRE regular expressions using named pattern subroutines.
(仔细阅读:)
我有一个包含可变数量的段(简化)的字符串:
$subject = 'AA BB DD '; // could be 'AA BB DD CC EE ' as well
我想现在匹配这些段并通过匹配数组返回它们:
$pattern = '/^(([a-z]+) )+$/i';
$result = preg_match_all($pattern, $subject, $matches);
这将仅返回捕获组2的 last 匹配:DD
。
有没有办法可以使用一个正则表达式执行检索所有子模式捕获(AA
,BB
,DD
)? preg_match_all
不适合这个吗?
$subject
和$pattern
均已简化。当然,使用AA
,BB
,...的一般列表,使用其他函数(例如explode
)或$pattern
的变体更容易提取。
但我特别询问如何使用preg_...
系列函数返回所有子组匹配。
对于真实案例,假设您有多个(嵌套)级别的子模式匹配变量。
这是伪代码中用来描述背景的一个例子。 想象以下内容:
令牌的常规定义:
CHARS := [a-z]+
PUNCT := [.,!?]
WS := [ ]
$subject
根据这些进行标记。标记化存储在一个标记数组(type,offset,...)中。
然后将该数组转换为字符串,每个标记包含一个字符:
CHARS -> "c"
PUNCT -> "p"
WS -> "s"
因此,现在可以在令牌流字符串索引上运行基于令牌(而不是字符类等)的正则表达式。 E.g。
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以某种方式为我工作,所以我可以节省它。
基本上都是这样。可能现在,为什么我简化了这个问题是可以理解的。
相关:
答案 0 :(得分:3)
试试这个:
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
)
)
答案 1 :(得分:3)
类似帖子:Get repeated matches with preg_match_all()
检查所选答案加上我可能会有用,我会在那里复制:
来自http://www.php.net/manual/en/regexp.reference.repetition.php:
当重复捕获子模式时,捕获的值是与最终迭代匹配的子字符串。
我个人放弃并将分两步完成。
修改强>:
我看到其他帖子someone声称lookbehind方法能够做到。
答案 2 :(得分:1)
您无法提取子模式,因为您编写正则表达式的方式只返回一个匹配项(同时使用^
和$
,并在主模式上使用+
如果你这样写,你会看到你的子组正确地存在:
$pattern = '/(([a-z]+) )/i';
(这仍然有一套不必要的括号,我只是留在那里作为说明)
答案 3 :(得分:1)
有没有办法可以通过一次正则表达式执行来检索所有匹配项(AA,BB,DD)? preg_match_all不适合这个吗?
您当前的正则表达式似乎是针对preg_match()调用。试试这个:
$pattern = '/[a-z]+/i';
$result = preg_match_all($pattern, $subject, $matches);
每条评论,我提到的红宝石正则表达式:
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");
但我认为你需要一个lexer / parser / tokenizer来在PHP中做同样的事情。 : - |
答案 4 :(得分:0)
修改强>
我没有意识到你原来要求的是什么。这是新的解决方案:
$result = preg_match_all('/[a-z]+/i', $subject, $matches);
$resultArr = ($result) ? $matches[0] : array();
答案 5 :(得分:0)
怎么样:
$str = 'AA BB CC';
$arr = preg_split('/\s+/', $str);
print_r($arr);
输出
(
[0] => AA
[1] => BB
[2] => CC
)
答案 6 :(得分:0)
我可能误解了你所描述的内容。您是否只是在寻找具有空格的字母组的模式?
// any subject containing words:
$subject = 'AfdfdfdA BdfdfdB DdD';
$subject = 'AA BB CC';
$subject = 'Af df dfdA Bdf dfdB DdD';
$pattern = '/(([a-z]+)\s)+[a-z]+/i';
$result = preg_match_all($pattern, $subject, $matches);
print_r($matches);
echo "<br/>";
print_r($matches[0]); // this matches $subject
echo "<br/>".$result;
答案 7 :(得分:0)
是的,你的解决方案是正确的,使用preg_match_all
preg_match_all是递归的,所以不要使用start-with ^
和end-with $
,以便preg_match_all
全部放入在阵列中找到了模式。
每对新的括号将添加一个表示不同匹配的新数组
使用?
进行可选匹配
您可以使用括号()
分隔报告的不同模式组,以要求找到一个组并添加到新数组中(可以允许您计算匹配项,或者对返回的数组中的每个匹配项进行分类) )
让我试着理解你的问题,以便我的回答符合你的要求。
您的$subject
不是您所寻找的好例子吗?
您希望pregmatch搜索将您在$subject
中提供的内容拆分为 4个类别,单词,字符< / strong>,标点符号和空格?那么数字呢?
你想要返回的匹配,是否指定了匹配的偏移量?
$subject = 'aa.bb cc.dd EE FFF,GG';
更适合现实生活吗?
我将在$subject
中采用您的基本示例,并使其能够准确地提供您的要求。
所以你可以编辑你的$subject
,以便我更适合你想要匹配的所有案例
原始'/^(([a-z]+) )+$/i';
让我发布, 你可以在http://www.spaweditor.com/scripts/regex/index.php
测试你的正则表达式 /([a-z])([a-z]+)/i
AA BB DD CD
Array
(
[0] => Array
(
[0] => AA
[1] => BB
[2] => DD
[3] => CD
)
[1] => Array
(
[0] => A
[1] => B
[2] => D
[3] => C
)
[2] => Array
(
[0] => A
[1] => B
[2] => D
[3] => D
)
)