如何在此正则表达式匹配中忽略带引号的字符串


How can ignore a string in quotes in this regex match?

如何忽略字符串"或"的实例,当它在单/双引号内?

当前表达式为/^(?='$)(.+?)(?:'s+or's+)(.+?)$/s

测试值1:$test or "default value"

测试值2:$errors->has('email') ? 'error or failure' : ''

应影响测试值1,但不应影响测试值2。

测试脚本:

更新$expression以进行测试。

<?php
function issetDefaults($value) {
    // Original expression with the issue
    //$expression = '/^(?='$)(.+?)(?:'s+or's+)(.+?)$/s';
    // @Avinash Raj's version; almost there; failing on test 2
    $expression = '/([''"])(?:(?!'1).)*or(?:(?!'1).)*'1(*SKIP)(*F)|^('S+) or ([''"].*[''"])/';
    return preg_replace($expression, 'isset($2) ? $2 : $3', $value);
}
// Tests
$tests = array(
    // should be affected
    '$test or "default value"',
    '$age or 90',
    // shouldn't be affected
    'myfunc(''foo or bar'')',
    '$errors->has(''email'') ? ''error or failure'' : ''''',
    '$errors->has("email") ? "error or failure" : ""',
    '$errors->has("email") ? "error ''or'' failure" : ""'
);

// Output tests
foreach ($tests as $key => $test) {
    $num = $key+1;
    echo '<strong>Original Value '.$num.'</strong>';
    echo '<pre>'.print_r($test,true).'</pre>';
    echo '<strong>Value '.$num.' after function</strong>';
    echo '<pre>'.print_r(issetDefaults($test),true).'</pre>';
    echo '<hr />';
}

下面的正则表达式将匹配没有被单引号或双引号括起来的字符串or

(['"])(?:(?!'1).)*or(?:(?!'1).)*'1(*SKIP)(*F)|'bor'b

or替换为任意字符串

演示

解释:

  • (['"])捕获'"符号。
  • (?:(?!'1).)*匹配0次或以上被捕获到第一组的字符以外的任何字符。
  • or匹配字符串or
  • (?:(?!'1).)*匹配0次或以上被捕获到第一组的字符以外的任何字符。
  • '1通过反向引用引用第一个捕获组。
  • (*SKIP)(*F)使整个匹配失败,|符号('bor'b)之后的字符将从剩余部分匹配。