有没有办法在preg_match_all()中移动/重置搜索指针?

时间:2011-06-30 19:28:51

标签: php regex

采取以下示例,

preg_match_all("/(^|-)[a-z]+(-|$)/i", "foo-bar-moo", $matches);

这(正确)返回以下匹配项

foo-
-moo

但是,我需要生成以下匹配输出

foo-
-bar-
-moo

有没有办法做到这一点?例如,通过在匹配后将搜索指针移回一个字符?

我唯一的另一个想法是将它放在while()循环中,删除每个循环上的匹配项,直到找到所有匹配项。

感谢。

编辑:我试图简化我的问题以使问题更清晰,但在这样做时,我似乎错误地表达了我的问题实际上是什么。道歉。

基本上我需要一种匹配字符串中单词的方法,其中紧接在前的字符或紧随其后的字符是某个字符,但同时不在匹配中捕获这些前导和尾随字符。

我的印象是你不能这样做,所以我决定捕捉领先/尾随字符并自己删除它们。这导致了我上面的问题。

Tim Pietzcker指出,我实际需要的是lookarounds

因此,对于上面的示例,解决方案如下,

preg_match_all('/(?<=^|-)[a-z]+(?=-|$)/', "foo-bar-moo", $result);

它输出,

foo
bar
moo

再次感谢您的回答和帮助。

4 个答案:

答案 0 :(得分:1)

我认为您必须使用offset中的preg_match参数。从0开始,获得-*[a-z]-*的第一场比赛。取matchOffset + matchLength - #dashesAtEnd并将其作为下一个preg_match电话的偏移量。

答案 1 :(得分:1)

使用环视并将捕获组放在环视表达式中。这允许您在单个preg_match_all()调用中执行此操作,并仍然捕获- es(如果存在):

preg_match_all('/(?<=(^|-))([a-z]+)(?=(-|$))/', $subject, $result, PREG_SET_ORDER);
for ($match = 0; $match < count($result); $match++) {
    echo $result[$match][1] . $result[$match][2] . $result[$match][3];
}

答案 2 :(得分:0)

怎么样?
preg_match_all("/(^|-)([a-z])+(-|$)/i", "foo-bar-moo", $matches);

你会得到[foo,bar,moo]。

答案 3 :(得分:0)

认为你需要:

Array
(
    [0] => foo-
    [1] => -bar-
    [2] => -moo
)

但正如我从您更新的问题中看到的那样,这也应该有效:

preg_match_all("/(?-)[a-z]+(?-)/i", "foo-bar-moo", $matches);

echo $matches[0];

Array
(
    [0] => foo
    [1] => bar
    [2] => moo
)