[英]Regex capturing repeating group in php without whitespace
我正在尝试通过PHP中的正则表达式解析字符串,该字符串始终具有以下格式: FooBar(,[0-9]{7}[0-9A-F]{8})+
或换句话说,它们都有一个开始值/单词,后跟1个或多个条目,每个条目是一个逗号( ,
),后跟7位数字和8个十六进制字符(数字或大写字母A至F)。
我的正则表达式捕获的是/^C7(,[0-9]{7}[0-9A-F]{8})+$/
这类作品。 在preg_match_all
使用时,它返回一个包含两个条目的数组,第一个按预期输入字符串,但是,在第二个数组中只有一个条目,即最后一个匹配的块。 (请参见示例)
我需要捕获与捕获组匹配的所有块。 我进行了一些研究,发现了这个答案,该答案可能是相同的问题: https : //stackoverflow.com/a/2205009/2989952 ,所以我将正则表达式调整为/(,[0-9]{7}[0-9A-F]{8})+$/
,但我仍然只有一场比赛。 可以在regex101.com上进行测试。 然后,我进行了更多的实验,发现,如果我更改输入字符串,以在块之间包含一个空格(或任何与此不匹配的字符),如下所示: C7,22801422CFE0F63 ,2280141C5EF0F63 ,22801402EFD0F63 ,2280138C5ED0F63 ,228024329897530 ,228023829877530
并再次将正则表达式调整为/(,[0-9]{7}[0-9A-F]{8})+/
它的功能与预期完全相同!
问题 :有没有一种方法可以实现此目的,使其与该循环组中的所有块都匹配而不在其之间添加空格? 如果是这样,怎么办?
为了说明问题:
没有空格 https://regex101.com/r/ilkZjD/1
空格/随机字符 https://regex101.com/r/mimBgz/1
目标 :第二个空格的行为,一个空格,但不添加空格(分别是不匹配的字符)。
考虑到这个https://stackoverflow.com/a/3513858/2989952答案,我有点找到了解决方案。 正则表达式/(?:,)([0-9]{7}[0-9A-F]{8})/
对我/(?:,)([0-9]{7}[0-9A-F]{8})/
。 https://regex101.com/r/LEEFzv/1。不过,我仍然想一种方法来匹配初始的FooBar
。 因为这表明传入的字符串应与此正则表达式完全匹配。
(我知道我可以为此简单地在第二个正则表达式中检查字符串,但是我很想在一个正则表达式中包含它)
范例 :
输入: 'C7,22801422CFE0F63,2280141C5EF0F63,22801402EFD0F63,2280138C5ED0F63,228024329897530,228023829877530'
那是你要的吗?
$in = 'C7,22801422CFE0F63 ,2280141C5EF0F63 ,22801402EFD0F63 ,2280138C5ED0F63 ,228024329897530 ,228023829877530';
preg_match_all('/(^\w+|\G)\h*(,[0-9]{7}[0-9A-F]{8})/', $in, $m);
print_r($m);
输出:
Array
(
[0] => Array
(
[0] => C7,22801422CFE0F63
[1] => ,2280141C5EF0F63
[2] => ,22801402EFD0F63
[3] => ,2280138C5ED0F63
[4] => ,228024329897530
[5] => ,228023829877530
)
[1] => Array
(
[0] => C7
[1] =>
[2] =>
[3] =>
[4] =>
[5] =>
)
[2] => Array
(
[0] => ,22801422CFE0F63
[1] => ,2280141C5EF0F63
[2] => ,22801402EFD0F63
[3] => ,2280138C5ED0F63
[4] => ,228024329897530
[5] => ,228023829877530
)
)
说明:
( : start group 1
^\w+ : beginning of line, 1 or more word characters
| : O
\G : match form this point
) : end group 1
\h* : 0 or more horizontal spaces
( : start group 2
, : a comma
[0-9]{7} : 7 digits
[0-9A-F]{8} : 8 hexa
) : end group 2
要捕获包括第一部分在内的所有卡盘,您可以尝试:
(?:FooBar|(?:[0-9]{7}[0-9A-F]{8})+)
说明
(?:
FooBar
|
(?:[0-9]{7}[0-9A-F]{8})+
关闭非捕获组
嗯...也许我听不懂这个问题,但是您的正则表达式可以在第一种情况下删除尾随+
(,[0-9]{7}[0-9A-F]{8})
您可以使用A标志(即Anchored )构建模式以获取连续的匹配项。 主要的兴趣是您可以提取值并使用超前检查同时检查行的格式:
$pattern = '~
(?!^) # fails at the start of the string
( \h*,\h* (?<value>[0-9]{7}[A-F0-9]{8}) )
# the first capture group is useful to shorten the
# the lookahead in the second branch.
|
(?<first>[a-zA-Z0-9]+)(?=(?1)*$)
~xA';
if ( preg_match_all($pattern, $yourstring, $matches) ) {
echo $matches['first'][0], PHP_EOL;
print_r(array_values(array_filter($matches['value'])));
}
A标志强制每个匹配项从字符串的开头或上一个匹配项的结尾开始。
第一个分支描述了逗号分隔的值,第二个分支描述了行的开头。
前瞻(?=(?1)*$)
检查行的结构。 如果失败,则不可能匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.