使用可选的反向引用来捕获可选地用引号括起来的字符串

时间:2011-06-18 22:49:09

标签: php regex string

我正在尝试构建一个能够使用正则表达式提取数据的解析器。

我希望能够匹配

这就是我现在所拥有的:

(\w+)\s+('|")([^\2\\]*(\\.[^\2\\]*)*)\2\s*;

([^\2\\]*(\\.[^\2\\]*)*)部分取自http://ad.hominem.org/log/2005/05/quoted_strings.php

不幸的是,这种模式存在两个问题。

首先,我希望能够捕获未用单/双引号括起来的字符串。

print "hello world";有效但print foobar;无法正常工作。我最终无法将反向引用\2作为可选项。

此外,我不知道它是否只是我封装正则表达式的方式,但我似乎无法解析此模式的多个实例。

如果我使用print 'hello'; print 'foobar';尝试正则表达式,它只会返回第一个print 'hello';部分。

提前感谢您的帮助。

修改

以下是我要解析的内容片段:

listen          80;
server_name     domain.com *.domain.com;
rewrite ^       http://www.domain.com$request_uri? permanent;

我试图用他们的参数捕获每个动作。基本上我不能解析NGINX配置文件:http://wiki.nginx.org/FullExample

2 个答案:

答案 0 :(得分:2)

像这样的字符类[^\2]中的反向引用doesn't work。它可能是一个多字符串,不能在那里使用。您可以使用((?!\2).)*构造解决这个问题。但如果你简化了匹配模式,那真的会更简单。

这里最简单的方法是分别列出三种可能的替代方案:

 /(\w+)\s+ (?: '([^']*)' |  "([^"]*)" | (\S+) ) \s*;/x

显然,您必须手动从结果集[2],[3]或[4]中获取结果。

答案 1 :(得分:1)

如果您想多次匹配,请改用preg_match_all。只要匹配的字符串不重叠,你就可以获得所有这些字符串。