$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, мне нужны обратные кавычки.
Почему это работает? Как я могу заставить его правильно соответствовать обратным кавычкам?






Вы используете чередование для обеих групп. Что вы можете сделать, используя свой шаблон, так это создать группа сброса ветвей(?| вместо группы без захвата.
Благодаря комментарию Виктор Стрибижев ваш шаблон может выглядеть так:
(?J)
\s*
(?|`(?P<col>(?:[^`\\]|\\.|``)*)`|(?P<col>\S+))
(?:\s+(?P<dir>asc|desc))?
\s*
\z
Демонстрация регулярных выражений | демонстрация Php
@dogsarecuttte Использование группы сброса ветвей заставляет альтернативы использовать одну и ту же группу захвата. Это работает в тестере регулярных выражений, потому что вы получаете одно или другое из-за чередования. Вы можете увидеть разницу в групповом выделении, используя client asc с обратными кавычками и без них, используя 2 разных шаблона. См. демо1 и демо2. Если вы проверите шаблон со сбросом ветки, вы увидите, что с обратными кавычками или без них группа остается прежней демо3
Альтернативой сбросу ветки является использование условного
# 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
Спасибо за решение моего вопроса, но не могли бы вы сказать мне, почему это работает на тестере регулярных выражений?