Php 如何使用preg_match_all()获取子组匹配的所有捕获?
更新/注意: 我想我可能正在寻找的是在PHP中获得 参考: (仔细阅读:)Php 如何使用preg_match_all()获取子组匹配的所有捕获?,php,regex,grammar,preg-match-all,Php,Regex,Grammar,Preg Match All,更新/注意: 我想我可能正在寻找的是在PHP中获得 参考: (仔细阅读:) 我有一个包含可变段数的字符串(简化): 现在,我想匹配段并通过matches数组返回它们: $pattern = '/^(([a-z]+) )+$/i'; $result = preg_match_all($pattern, $subject, $matches); 这将只返回捕获组2的最后一个匹配项:DD 是否有一种方法可以通过一次regex执行检索所有子模式捕获(AA,BB,DD)?preg\u match\u
我有一个包含可变段数的字符串(简化): 现在,我想匹配段并通过matches数组返回它们:
$pattern = '/^(([a-z]+) )+$/i';
$result = preg_match_all($pattern, $subject, $matches);
这将只返回捕获组2的最后一个匹配项:DD
是否有一种方法可以通过一次regex执行检索所有子模式捕获(AA
,BB
,DD
)?preg\u match\u all
是否适用于此
这个问题是一个概括。
$subject
和$pattern
都被简化。很自然地,有了这样的总列表,AA
,BB
。。使用其他函数(例如explode
)或使用$pattern
的变体更容易提取
但是我特别想问的是,如何返回所有与preg.
-函数族匹配的子组
对于现实生活中的情况,假设您有多个(嵌套的)级别的不同数量的子模式匹配
例子
这是一个用伪代码来描述一点背景的例子。想象一下:
令牌的常规定义:
CHARS := [a-z]+
PUNCT := [.,!?]
WS := [ ]
$subject
get的标记化基于这些。标记化存储在标记数组(类型、偏移量等)中
然后将该数组转换为字符串,每个标记包含一个字符:
CHARS -> "c"
PUNCT -> "p"
WS -> "s"
因此,现在可以基于令牌流字符串索引上的令牌(而不是字符类等)运行正则表达式。例如
regex: (cs)?cp
用标点符号表示一组或多组字符
因为我现在可以将自定义标记表示为regex,所以下一步是构建语法。这只是一个例子,这是一种ABNF风格:
words = word | (word space)+ word
word = CHARS+
space = WS
punctuation = PUNCT
如果我现在将单词的语法编译成一个(标记)正则表达式,我希望自然地拥有每个单词的所有子组匹配
我可以一直编码到这一点。然后我遇到了这样一个问题:分组匹配只包含了最后一个匹配
因此,我可以选择自己为语法创建一个自动机(为了保持语法表达式的通用性,我想阻止它),或者让preg_match在某种程度上为我工作,这样我就可以省掉它
基本上就这些。也许现在可以理解为什么我简化了这个问题
相关的:
- 你的
不是你想要的东西的好例子$subject
- 您希望预匹配搜索将您在
中提供的内容分成4个类别、单词、字符、标点和空白?那么数字呢$subject
- 您是否希望返回的匹配项指定匹配项的偏移量 Does
- 编辑
我不知道你最初要求的是什么。以下是新的解决方案:
$result = preg_match_all('/[a-z]+/i', $subject, $matches);
$resultArr = ($result) ? $matches[0] : array();
试试这个:
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
)
)
无法提取子模式,因为编写正则表达式的方式只返回一个匹配项(同时使用
^
和$
以及主模式上的+
)
如果以这种方式编写,您将看到您的子组位于正确的位置:
$pattern = '/(([a-z]+) )/i';
(这仍然有一组不必要的括号,我只是把它放在那里以示说明)怎么样:
$str = 'AA BB CC';
$arr = preg_split('/\s+/', $str);
print_r($arr);
输出:
(
[0] => AA
[1] => BB
[2] => CC
)
我可能误解了你的描述。你只是在寻找一组字母之间有空格的模式吗
// 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;
//任何包含单词的主题:
$subject='AfdfdfdA BdfdfdB DdD';
$subject='AA BB CC';
$subject='Af-dfdA-Bdf-dfdB-DdD';
$pattern='/([a-z]+)\s)+[a-z]+/i';
$result=preg_match_all($pattern,$subject,$matches);
打印(匹配项);
回声“
”;
打印($matches[0]);//这与$subject匹配
回显“
.”$result;
是否有一种方法可以通过一次正则表达式执行检索所有匹配项(AA、BB、DD)?preg_match_不都适合这样吗
您当前的正则表达式似乎用于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");
句子=%r{
(?猫狗){0}
(?吃|喝){0}
(?水|骨){0}
(?大|臭){0}
(?(\g\s)?){0}
\s\g\g\s\g\s\g\g\g
}x
md=句子匹配(“猫喝水”);
md=句子.match(“大狗吃臭骨头”);
但我认为您需要一个lexer/parser/tokenizer来在PHP中完成同样的工作-| 是的,您的权利您的解决方案是使用
preg\u match\u all
preg\u match\u all是递归的,因此不要使用以^
开始,以$
结束,这样preg\u match\u all
将所有找到的模式放在一个数组中
每对新括号将添加一个新数组,指示不同的匹配项
使用?
进行可选匹配
您可以用括号分隔报告的不同模式组()
,以请求在新数组中找到并添加一个组(可允许您计算匹配项,或对返回数组中的每个匹配项进行分类)
需要澄清
让我试着理解你们的问题,以便我的答案和你们的要求相符
$subject='aa.bb cc.dd EE FFF,GG'代码>更适合真实生活的示例?
$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");
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
)
)