多次匹配相同的模式

时间:2014-04-29 13:45:52

标签: php regex

我有一个字符串,其结构如下:

~ foo;
text 1
~ foo;
text 2
~ foo;
...
~ foo;
text n
~ foo;

我正在尝试将text 1, text 2 .. text n放入数组中,但我无法弄清楚如何执行此操作,所以我的问题是:如何将此信息转换为数组?< /强>

我尝试了以下正则表达式:!~\s*([a-z0-9 ]+)\s*(;|\r|\r\n)([^~]*)~\s*\\1!i,但它似乎只匹配第一次出现。 (我试过preg_match_all

**更新:示例:**

我的字符串:

// .. text before... //
~ Key; 
  some random text
~ Key;
  another random text
~ Key;

// .. some random text .. //

~ Key2; some random text again
~ Key2; 
another some random text again
~ Key2;

输出应为:

Array
(
    [Key] => Array
        (
            [0] => some random text
            [1] => another some random text
        )

    [Key2] => Array
        (
            [0] => some radom text again
            [1] => another some radom text again
        )

)

不需要完全使用正则表达式

2 个答案:

答案 0 :(得分:2)

使用preg_replace_callback获取whished结构的原始方法:

$pattern = '/^~ (\w+);\s*(.+?)\s*(?=\R~ \1;)/ms';
$res = array();

preg_replace_callback($pattern,
                      function ($m) use (&$res) { $res[$m[1]][] = $m[2]; },
                      $str);

print_r($res);

注意:我假设&#34;随机文字&#34;可以是多行,如果不是这样,您可以将模式更改为/^~ (\w+);\h*\R?\h*(\N+?)\h*(?=\R~ \1;)/m

\R是包含任何类型换行符的原子组的快捷方式 \N匹配除换行符之外的所有字符(无论是否为单行)

答案 1 :(得分:0)

您必须继续尝试preg_match_all,因为诚实地说,这是您需要的工具。

原因是它执行了全局搜索,这正是您在说出此要求时所表达的要求:

  

&#34;但它似乎只匹配第一次出现。&#34;

那是preg_match_all的用途。


无论如何,你的正则表达式的问题是反向引用\1

当您捕获text 1时,它会一直在寻找text 1而不是text \d

如果你能给出更真实的数据样本,我可以为它创建一个表达式。