Andy Fleming
Andy Fleming

Reputation: 7865

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

How can I ignore instances of the string "or" when it is inside single/double quotes?

The current expression is /^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s

Test value 1: $test or "default value"

Test value 2: $errors->has('email') ? 'error or failure' : ''

Test value 1 should be affected, but value 2 should be unaffected.

Test script:

Update $expression to test.

<?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 />';
}

Upvotes: 0

Views: 52

Answers (1)

Avinash Raj
Avinash Raj

Reputation: 174706

The below regex would matches the string or which was not enclosed within single or double quotes,

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

Replace or with whatever string you want.

DEMO

Explanation:

  • (['"]) Captures ' or " symbols.
  • (?:(?!\1).)* Matches any character not the one which was captured into the first group zero or more times.
  • or Matches the string or.
  • (?:(?!\1).)* Matches any character not the one which was captured into the first group zero or more times.
  • \1 First captured group was referred through back referencing.
  • (*SKIP)(*F) Makes the whole match to fail and the characters which are following | symbol(\bor\b) would be matched from the remaining part.

Upvotes: 3

Related Questions