我不确定是否应该将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\""
答案 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
会为您提供abcd
和ef'gh