假设我们有这段文字:
...
settingsA=9, 4.2
settingsB=3, 1.5, 9, 2, 4, 6
settingsC=8, 3, 2.5, 1
...
问题是如何通过一个步骤捕获特定行中的所有数字?
单步表示:
假设我要捕获以
settingsB=
开头的行中存在的所有数字。最终结果应如下所示:3
1.5
9
2
4
6
我的尝试失败:
<?php
$subject =
"settingsA=9, 4.2
settingsB=3, 1.5, 9, 2, 4, 6
settingsC=8, 3, 2.5, 1";
$pattern = '([\d\.]+)(, )?' // FAILED!
$pattern = '(?:settingsB=)(?:([\d\.]+)(?:, )?)' // FAILED!
$pattern = '(?:settingsB=)(?:([\d\.]+)(?:, )?)+' // FAILED!
$pattern = '(?<=^settingsB=|, )([\d+\.]+)' // FAILED!
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
if ($matches) {
print_r($matches);
}
?>
更新1:不幸的是,@Saleem的示例使用多个步骤而不是单个步骤。我并不是说他的例子很糟糕(实际上是可行的),但我想知道是否还有另一种方法以及如何做。有任何想法吗?
更新2: @bobble bubble为此挑战提供了完美的解决方案。
最佳答案
您可以使用 \G
anchor将匹配项粘到上一个匹配项的末尾。在期望的部分之前也使用 \K
to reset的此模式将与PCRE regex风格一起使用。
(?:settingsB *=|\G(?!^) *,) *\K[\d.]+
(?:
打开一个non-capturing group进行交替settingsB
,然后是 *
任何空间,然后是文字=
|\G(?!^)
或在上一个比赛结束但未开始的地方继续 *,
并匹配逗号,并在其前面加上可选的空格)
轮换结束(非捕获组) *\K
[\d.]+
匹配一个或多个数字和句点。 如果序列包含制表符或换行符,请使用
\s
代替空格字符。See demo at regex101或PHP demo at eval.in
使用or this more compatible pattern而不是
\K
的capturing group应该可以在支持\G
anchor (Java,.NET,Ruby ...)的任何正则表达式中使用