PHP Regex用于在第一次出现字符时拆分字符串

时间:2010-08-13 18:48:59

标签: php regex preg-match preg-match-all

这可能是一个蹩脚的问题,但我是正则表达式的新手。我有一些格式的文本数据:

  

公司名称:公司名称,地点。
公司地址:部分,   地址,这里。
链接:   http://www.somelink.com

现在,我想使用正则表达式将它们拆分为一个名称:值对的数组。我正在尝试的正则表达式是/(.*):(.*)/preg_match_all(),它在前两行中运行良好,但在第三行它在一个部分返回“Link:http:”和“// www。 somelink.com“在其他地方。

那么,有没有办法只在第一次出现的角色':'时分割线?

2 个答案:

答案 0 :(得分:1)

使用否定字符类(see on rubular.com):

/^([^:]*):(.*)$/m

[…]character class。像[aeiou]这样的东西匹配任何一个小写元音。 [^…]否定的字符类。 [^aeiou]除了小写元音之外的任何内容匹配。

模式开头和结尾的^$是行anchors的开头和结尾。 m修饰符会启用multi-line mode

原始模式的问题在于,当你可能更具体时,你(ab)使用.,并且由于*是贪婪的,所以第一组是超级匹配的。尝试通过使重复不情愿来“修复”它是很诱人的,但更好的是 MUCH 更具体,并说第一组匹配除:之外的任何内容。

但请注意,这是一个匹配的模式,带有捕获。它实际上不是仅与分隔符匹配的拆分模式。分隔符模式实际上只是:

相关问题


PHP代码段

鉴于此:

$text = <<<EOT
Company Name: Name of the company, place.
Company Address: Some, address, here.
Link: http://www.somelink.com
EOT;

preg_match_all('/^([^:]*):(.*)$/m', $text, $matches, PREG_SET_ORDER);

print_r($matches);

输出为(as seen on ideone.com):

Array
(
    [0] => Array
        (
            [0] => Company Name: Name of the company, place.
            [1] => Company Name
            [2] =>  Name of the company, place.
        )

    [1] => Array
        (
            [0] => Company Address: Some, address, here.
            [1] => Company Address
            [2] =>  Some, address, here.
        )

    [2] => Array
        (
            [0] => Link: http://www.somelink.com
            [1] => Link
            [2] =>  http://www.somelink.com
        )

)

答案 1 :(得分:0)

你可能想要像/(.*?):(.*)/这样的东西。 ?之后的*会使其“非贪婪”,因此它将尽可能少地消耗文本。我认为这对你的情况有用。默认情况下,*是“贪婪的”,并尝试尽可能多地重复匹配。

修改:有关使用*+运算符匹配重复的详情,请参阅here