用于匹配字符串中单引号单词的正则表达式模式,并忽略转义的单引号

时间:2012-11-06 23:49:28

标签: php regex preg-match

我的PHP代码如下所示:

$input = "City.name = 'New York'";
$literal_pattern = '/\'.[^\']*\'/';
preg_match($literal_pattern, $input, $token);
echo $token[0]; // prints 'New York'

我的正则表达式需要使用转义的单引号来抓取文字,如:

$input = "City.name = 'New \' York'";
$literal_pattern = ???????????;
preg_match($literal_pattern, $input, $token);
echo $token[0]; // should prints 'New \' York'

$ literal_pattern的遗产是什么?

4 个答案:

答案 0 :(得分:2)

没有这个条件,简单......

/('[^']*')/

...就足够了,当然:匹配“单引号的所有序列,后跟任意数量的非单引号符号,然后再单引号”。

但是我们需要为这里的两个事物做好准备 - 包括“正常”和“逃脱”。所以我们应该为我们的模式添加一些东西:

/('[^'\\]*(?:\\.[^'\\]*)*')/

它可能看起来很奇怪(而且确实如此),但它实际上也非常简单:匹配...的序列...

  • 单引号符号......
  • ...后跟零个或多个“普通”字符(不是'\),
  • ...接着是子表达式(“转义”符号,然后是零或更多“正常”符号),重复0次或更多次......
  • 后跟单引号。

示例:

$input   = "City.name = 'New \\' York (And Some Backslash Fun)\\\\'\\'"; 
# ...as \' in any string literal will be parsed as a _single_ quote

$pattern = "/('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')/";
# ... a choice: escape either slashes or single quotes; I choose the former

preg_match($pattern, $input, $token);
echo $token[0]; // 'New \' York (And Some Backslash Fun)\\'

答案 1 :(得分:2)

这是您要查找的正则表达式:/\'(\\.|[^\'\\])*\'/

在PHP中,这看起来像$literal_pattern = '/(\'(?:\\.|[^\'\\])*\')/';

答案 2 :(得分:1)

正则表达式自动贪婪,因此它将使用文字捕获尽可能多的数据。因此,如果您认识到“' s之间的所有内容”,它将在第一个和最后一个'之间捕获任何内容。

因此,您可以安全地执行此操作:

$literal_pattern = "#('.*')#";

示例:http://ideone.com/gI5bXs

注意:正如@m.buettner所指出的那样,只有输入中有一个'个字符串的字符串时,此方法才有效。

答案 3 :(得分:0)

您可以使用负后瞻性匹配。 http://www.regular-expressions.info/lookaround.html

  

(?<!a)b匹配“b”,前面没有“a”,使用负面的背后隐藏

唯一的问题是我非常确定PHP正则表达式不支持它。如果它们得到支持,正则表达式将如下所示:

/(?<!\\)'(.*?)(?<!\\)'/

我的建议是使用简单的解析器。这里有一些我刚刚从脑海中浮现的东西(显然是伪代码):不能保证它的逻辑可以用于你的目的,但实际上并不是很难自己构建。

let inString = false
let escaping = false
let match = ''    
for each letter in string
    if letter == "\\" and not escaping
        escaping = true
    else
        if letter == "'" and not escaping
            inString = not inString
        else if inString
            match += letter
        escaping = false
return match