我不确定是否应该将 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\""
我不确定是否应该将 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\""
您不能使用正则表达式来执行此操作,因为您正在尝试解析非上下文无关语法。编写解析器。
大纲:
\
就记住了。"
或'
检查前一个字符是否为\
. 你现在有了你的定界条件。您想要的结果集似乎修剪了空格,您还丢失了几个\
s,也许这是一个错误,但它可能很重要。
我希望:
[0] = " ok " // <-- spaces here
[1] = "that\\'s cool"
[2] = " \"yeah that's \\\"cool\\\"\"" // leading space here, and \" remains
实际上,您可能会惊讶地发现您可以在正则表达式中执行此操作:
preg_match_all("((?|\"((?:\\\\.|[^\"])+)\"|'((?:\\\\.|[^'])+)'|(\w+)))",$string,$m);
所需的结果数组将位于$m[1]
.
您可以使用正则表达式来做到这一点:
$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
会给你abcd
和ef'gh