1

我想匹配一个单引号或双引号,后跟任意数量的不是刚刚匹配的字符的字符,然后是匹配的字符之一:

"--'__'--"

应该匹配每端的双引号。但是,我希望匹配具有所有格性,因为任何已经测试过的字符都不应包含在任何未来的匹配中:

"--'__'--

应该匹配,因为开头的双引号后面永远不会跟着另一个。我想出了:

(?P<q>['"])(?>((?!(?P=q)).)*)(?P=q)

但这仍然与我上面的第二个字符串示例相匹配,中间的单引号。我不明白为什么原子组不能做到这一点。我也无法通过任何其他原子分组安排来实现这一点。

此外,如果有可能只匹配引号之间的字符,同时断言引号存在,那就太好了。因为后向断言是固定宽度,所以我不能使用反向引用来断言捕获的单引号或双引号组发生在负前瞻之前。

4

1 回答 1

0

假设每行只有一个有效的带引号的子字符串,这可能是一个很好的起点:

<?php // test.php Rev:20120105_1800
// Return array of valid quoted substrings, one per line.
function getArrayOfOnePerLineValidQuotedSubstrings($text) {
    $re = '%
        # Match line w/1 valid "single" or "double" substring.
        ^               # Anchor to start of line.
        [^\'"]*         # Everything up to first quote.
        (?|             # Branch reset group $1: Contents.
          "([^"]*)"     # Either $1.1 Double quoted,
        | \'([^\']*)\'  # or $1.2 Single quoted contents.
        )               # End $1: branch reset group.
        [^\'"]*         # Everything after quoted sub-string.
        $               # Anchor to end of line.
        %xm';
    if (preg_match_all($re, $text, $matches)) {
        return $matches[1];
    }
    return array();
}
// Fetch test data from file.
$data = file_get_contents('testdata.txt');
// Get array of valid quoted substrings, one per line.
$output = getArrayOfOnePerLineValidQuotedSubstrings($data);
// Display results.
$count = count($output);
printf("%d matches found.\n", $count);
for ($i = 0; $i < $count; ++$i) {
    printf("  match[%d] = {%s}\n", $i + 1, $output[$i]);
}
?>

此正则表达式匹配包含一个有效的带引号的子字符串的每一行,并跳过具有无效(即"--'__'--具有不平衡的双引号子字符串)或没有带引号的子字符串的行。对于匹配的行,有效引用子字符串的内容在 group 中返回$1。该函数返回匹配的子字符串的数组。

如果您的数据每行包含多个子字符串,或者引用的子字符串或引用的子字符串之间的内容可能包含转义的引号,则可以制定更复杂的解决方案。

于 2012-01-05T01:38:21.663 回答