php regex:使用引号进行匹配,但不捕获它们

时间:2013-07-26 16:09:38

标签: php regex preg-match-all

我不确定是否应该将preg_match,preg_match_all或preg_split与delim捕获一起使用。我也不确定正确的正则表达式。

鉴于以下内容:

$string = " ok 'that\\'s cool' \"yeah that's \\\"cool\\\"\"";

我想获得一个包含以下元素的数组:

[0] = "ok"
[1] = "that\'s"
[2] = "yeah that's \"cool\""

3 个答案:

答案 0 :(得分:1)

您无法使用正则表达式执行此操作,因为您尝试解析非上下文无关语法。写一个解析器。

概要

  • 如果您看到\,请按字符逐字阅读。
  • 如果您看到"'检查前一个字符是否为\。你现在有了分界条件。
  • 以这种方式记录所有令牌

你想要的结果集似乎修剪了空格,你也失去了几个\ s,也许这是一个错误,但它可能很重要。

我希望:

[0] = " ok " // <-- spaces here
[1] = "that\\'s cool"
[2] = " \"yeah that's \\\"cool\\\"\"" // leading space here, and \" remains

答案 1 :(得分:1)

实际上,您可能会惊讶地发现可以在正则表达式中执行此操作:

preg_match_all("((?|\"((?:\\\\.|[^\"])+)\"|'((?:\\\\.|[^'])+)'|(\w+)))",$string,$m);

所需的结果数组将位于$m[1]

答案 2 :(得分:0)

您可以使用正则表达式执行此操作:

$pattern = <<<'LOD'
~
(?J) 

# Definitions #
(?(DEFINE)
  (?<ens> (?> \\{2} )+ ) # even number of backslashes

  (?<sqc> (?> [^\s'\\]++  | \s++ (?!'|$)    | \g<ens> | \\ '?+    )+ ) # single quotes content
  (?<dqc> (?> [^\s"\\]++  | \s++ (?!"|$)    | \g<ens> | \\ "?+    )+ ) # double quotes content
  (?<con> (?> [^\s"'\\]++ | \s++ (?!["']|$) | \g<ens> | \\ ["']?+ )+ ) # content
)
# Pattern #
    \s*+ (?<res> \g<con>)
| ' \s*+ (?<res> \g<sqc>) \s*+ '?+
| " \s*+ (?<res> \g<dqc>) \s*+ "?+ 
~x
LOD;
$subject = " ok 'that\\'s cool' \"yeah that's \\\"cool\\\"\"";

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
foreach($matches as $match) {
    var_dump($match['res']);
}

我选择在所有结果中修剪空格,然后" abcd "会给abcd。此模式允许您想要的所有反斜杠。如果引用的字符串未在字符串的末尾处关闭,则字符串的结尾将被视为结束引用(这就是为什么我使结束引号可选)。因此,abcd " ef'gh会为您提供abcdef'gh