PHP: preg_match_all() - how to find all occurrences of OR seperated substrings with a regex correctly?
我的任务是在一个只有数字的字符串中查找所有连续的数字。不过,我并不是在寻找更好的regex来实现这一点,而是在寻找匹配子字符串的正确regex。
这就是我如何构建我的regex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $regex ="";
for($i=0;$i<10;$i++) {
$str ="";
for($a=0;$a<10;$a++) {
if($a > $i) {
$str .= $a;
if(strlen($str)>1) {
$regex .="|".$str."";
}
}
}
}
$myregex ="/".ltrim($regex,"|")."/";
echo $myregex; |
结果:
/12|123|1234|12345|123456|1234567|12345678|123456789|23|234|2345|23456|234567|2345678|23456789|34|345|3456|34567|345678|3456789|45|456|4567|45678|456789|56|567|5678|56789|67|678|6789|78|789|89/
然后我这样做:
1 2 3 4
| $literal = '234121678941251236544567812122345678';
$matches = [];
preg_match_all($myregex,$literal,$matches);
var_dump($matches); |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| array(1) {
[0]=>
array(13) {
[0]=>
string (2)"23"
[1]=>
string (2)"12"
[2]=>
string (2)"67"
[3]=>
string (2)"89"
[4]=>
string (2)"12"
[5]=>
string (2)"12"
[6]=>
string (2)"45"
[7]=>
string (2)"67"
[8]=>
string (2)"12"
[9]=>
string (2)"12"
[10]=>
string (2)"23"
[11]=>
string (2)"45"
[12]=>
string (2)"67"
}
} |
但是,我希望找到所有正在发生的子字符串(匹配后不转到下一个字符),例如:
23,234,34,12,67,678,6789,78,789,89,12, ...
然而,我尝试了用括号,+,和…并且没有找到找到所有匹配的正确regex(抱歉,仍然有点regex noob)。如何修改正则表达式?
- 没有办法在远处找到重叠的火柴。您必须手动拆分$liiteral号池,然后用regex断言每个子字符串。
正则表达式的顺序很重要。我不确定这样做是否完全解决了问题,这样做的方法可能从根本上有缺陷,但您可以尝试这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $regex = [];
for($i=0;$i<10;$i++) {
$str ="";
for($a=0;$a<10;$a++) {
if($a > $i) {
$str .= $a;
if(strlen($str)>1) {
$regex[] = $str;
}
}
}
}
usort($regex, function($a,$b){
return strlen($b) <=> strlen($a);
});
$myregex = '/'.implode('|', $regex).'/'; |
它的作用是使数字序列成为一个数组,然后按长度对它们排序,并首先将它们排序为最长的序列。最终结果是(匹配后)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| array(1) {
[0]=>
array(9) {
[0]=>
string (3)"234"
[1]=>
string (2)"12"
[2]=>
string (4)"6789"
[3]=>
string (2)"12"
[4]=>
string (3)"123"
[5]=>
string (5)"45678"
[6]=>
string (2)"12"
[7]=>
string (2)"12"
[8]=>
string (7)"2345678"
}
} |
还要注意,宇宙飞船操作员<=>只在PHP7工作。+
希望它有帮助。
沙箱
and not go to the next chars after a match
我认为,如果你想在2345607中同时找到232342345,用regex是不可能的。但是,如果它匹配一个较长的序列,那么逻辑上它只能匹配一个较短的序列。所以你可以把右手边的数字剪掉,直到长度为2,然后得到匹配的结果。
- 这并不是我想要的,因为我试图用regex匹配所有可能的子字符串,但作为我的初始方法,它首先检查更长的文本,效果更好。还要感谢宇宙飞船的操作者还不知道吗??
- 如果你知道最长的比赛,那么从逻辑上说你拥有所有的比赛。只要较小的匹配都是每个较大匹配的子集。
- 是的-如果它匹配一个较长的,它也必须匹配相应的较短的,因此我只需要再次使用regex递归键拆分匹配项,所有匹配项都在那里。不完善,因为需要一个额外的功能,但足够好。
- 您可以使用substr($match,0,-1)并删除最右边的数字,直到只剩下2个数字。
- 你也不需要赛前比赛,只要赛前比赛就行了。preg_match_all用于多行字符串。不适用于在单行字符串中查找所有匹配项。下面是一个很好的例子,说明preg-match-all的用途,github.com/artisticphoenix/misc/blob/master/lexers/&hellip;这使用了一个大的HTML字符串,并将其缩小。