获取字符之间的所有出现以获得相同的结果

时间:2016-05-16 16:31:58

标签: php regex preg-match-all pcre

我正在查看字符串3-431 a4-2 4-13内部并希望找到3-431a4-24-13。我使用以下模式:

/(.*-.* )*/gU

我没有遇到问题就得到了所需的结果:Online demo

问题是 - 当我想查看以其他子串开头和结束的字符串时,如何实现相同的结果,例如[]

如果我将主题修改为[3-431 a4-2 4-13 ]并将正则表达式修改为/\[(.*-.* )*\]/gU我只会收到最后一次出现:4-13并且我的结果与第1次相同例。 Online demo

为什么会这样,我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

您不需要使用正则表达式,您可以使用explode或按空格分割:

$str  = "3-431 a4-2 4-13";
$parts = explode(" ", $str);
echo $parts [0]; // 3-431
echo $parts [1]; // a4-2
echo $parts [2]; // 4-13

但是,如果您仍想使用正则表达式,则可以使用:

$re = "/(\\w+-\\w+)/"; 
$str = "3-431 a4-2 4-13"; 

preg_match_all($re, $str, $matches);

<强> Regex demo

顺便说一下,如果你的字符串总是用空格分隔,那么你也可以使用这个正则表达式:

$re = "/(\\S+)/"; 
$str = "3-431 a4-2 4-13"; 

preg_match_all($re, $str, $matches);

<强> Regex demo

另一方面,如果您的字符串以[]开头和结尾,则为[3-431 a4-2 4-13 ]。想法是利用丢弃技术,你可以使用这个正则表达式:

[[\]](*SKIP)(*FAIL)|(\S+)

<强> Working demo

此外,使用preg_split获取上述字符串的相同结果:

$exploded = preg_split('[[\]\s]+', '[3-431 a4-2 4-13]', NULL, PREG_SPLIT_NO_EMPTY)

答案 1 :(得分:0)

首先,您应该使用.+而不是.*,因为+至少意味着一次。然后你的正则表达式是:

/\[(\w+-\w+)*\s*\]/sgU

答案 2 :(得分:0)

如果您仍想使用正则表达式,这将起作用:

(^|\])[^[]*\[([^[]*-[^[]* )*(*SKIP)(*FAIL)|(.*-.* )+

基本上,如果事件发生在[]之外,则会失败。

你只获得一场比赛的原因是全局修饰符只会在第一场比赛结束后匹配另一场比赛,在你的情况下是在比赛结束后。