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

时间:2014-07-25 08:56:34

标签: php regex preg-replace

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

当前表达式为/^(?=\$)(.+?)(?:\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 />';
}

1 个答案:

答案 0 :(得分:3)

以下正则表达式将匹配未包含在单引号或双引号内的字符串or

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

or替换为您想要的任何字符串。

DEMO

<强>解释

  • (['"])捕获'"符号。
  • (?:(?!\1).)*匹配任何不是被捕获到第一组中的任何字符零次或多次。
  • or匹配字符串or
  • (?:(?!\1).)*匹配任何不是被捕获到第一组中的任何字符零次或多次。
  • \1第一个被捕获的群体是通过反向引用来引用的。
  • (*SKIP)(*F)使整个匹配失败,并且跟随|符号(\bor\b)的字符将与其余部分匹配。