这可能是一个蹩脚的问题,但我是正则表达式的新手。我有一些格式的文本数据:
公司名称:公司名称,地点。
公司地址:部分, 地址,这里。
链接: http://www.somelink.com
现在,我想使用正则表达式将它们拆分为一个名称:值对的数组。我正在尝试的正则表达式是/(.*):(.*)/
和preg_match_all()
,它在前两行中运行良好,但在第三行它在一个部分返回“Link:http:”和“// www。 somelink.com“在其他地方。
那么,有没有办法只在第一次出现的角色':'时分割线?
答案 0 :(得分:1)
使用否定字符类(see on rubular.com):
/^([^:]*):(.*)$/m
[…]
是character class。像[aeiou]
这样的东西匹配任何一个小写元音。 [^…]
是否定的字符类。 [^aeiou]
与除了小写元音之外的任何内容匹配。
模式开头和结尾的^
和$
是行anchors的开头和结尾。 m
修饰符会启用multi-line mode。
原始模式的问题在于,当你可能更具体时,你(ab)使用.
,并且由于*
是贪婪的,所以第一组是超级匹配的。尝试通过使重复不情愿来“修复”它是很诱人的,但更好的是 MUCH 更具体,并说第一组匹配除:
之外的任何内容。
但请注意,这是一个匹配的模式,带有捕获。它实际上不是仅与分隔符匹配的拆分模式。分隔符模式实际上只是:
。
鉴于此:
$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。