Как preg_match PCRE выражение? - PullRequest
2 голосов
/ 27 мая 2019
$key="`client` asc";
preg_match('
                ~(?J)
                    \s*
                    (?:`(?P<col>(?:[^`\\\\]|\\\\.|``)*)`|(?P<col>\S+))
                    (?:\s+(?P<dir>asc|desc))?
                    \s*
                \z~Axi', $key, $m);
print_r($m);

Это регулярное выражение заполняет клавишу col при проверке здесь

https://regex101.com/r/i00sEn/1

Он не работает корректно на моей локальной PHP 5.6 машине или на этом 7.3 интерпретаторе.

http://sandbox.onlinephpfunctions.com/code/915a26b741c6d086f21129f60af2420c74cf9f89

Это работает везде, если я убираю обратные пометки, но поскольку целью этого кода является анализ предложений SQL ORDER BY, мне нужны обратные пометки.

Почему это работает? Как я могу сделать так, чтобы он соответствовал обратным меткам?

Ответы [ 2 ]

3 голосов
/ 27 мая 2019

Вы используете чередование для обеих групп.Используя шаблон, вы можете создать группу сброса ветвей (?| вместо группы без захвата.

Благодаря комментарию Wiktor Stribiżew yourшаблон может выглядеть так:

(?J)
                    \s*
                    (?|`(?P<col>(?:[^`\\]|\\.|``)*)`|(?P<col>\S+))
                    (?:\s+(?P<dir>asc|desc))?
                    \s*
                \z

Regex demo | Php demo

1 голос
/ 28 мая 2019

Альтернативой сбросу ветки является использование условного

 # http://sandbox.onlinephpfunctions.com/code/551b5ecba6d554cdeff616f193fca003cd777014

 (?xis-)
 \A                                    # BOS
 \s* 
 (?:
      ( `? )                                # (1), Optional backtick
      (?<col>                               # (2 start), Col body
           (?(?<= ` )                            # Conditional, is backtick behind ?
                (?: [^`\\] | \\ . | `` )*             # yes, match backtick body
             |  \S+                                   # no, match consecutive non-whitespaces
           )
      )                                     # (2 end)
      \1                                    # Backref to optional backtick
 )
 (?:                                   # Optional column direction 
      \s+ 
      (?<dir> asc | desc )                  # (3), ascending or descending
 )?
 \s* 
 \z                                    # EOS
...