ожидаемое поведение расширенного регулярного выражения posix:(()|abc)xyz

StackOverflow https://stackoverflow.com/questions/1436194

  •  07-07-2019
  •  | 
  •  

Вопрос

На моей машине OS X 10.5.8, используя функции regcomp и regexec C для сопоставления расширенного регулярного выражения "(() | abc) xyz", я нахожу соответствие для строки "abcxyz", но только со смещением 3 до смещения 6.Я ожидал, что будет сопоставлена вся строка целиком и что я увижу дополнительное соответствие для начальной части строки "abc".

Когда я пробую тот же шаблон и текст с помощью awk на том же компьютере, он показывает совпадение для всей строки, как я и ожидал.

Я ожидаю, что проблема может быть в моем ограниченном опыте работы с регулярными выражениями.Кто-нибудь может объяснить, что происходит?Допустимо ли мое регулярное выражение?Если да, то почему он не соответствует всей строке целиком?

Я понимаю, что "((abc) {0,1})xyz" можно было бы использовать в качестве альтернативы, но интересующий шаблон автоматически генерируется из другого формата шаблона, и устранение экземпляров "()" - это дополнительная работа, которой я хотел бы избежать, если это возможно.

Для справки, флаги, которые я передаю regcomp, состоят только из REG_EXTENDED .Я передаю пустой набор флагов (0) в regexec.

Это было полезно?

Решение

Тот Самый POSIX стандарт гласит:

9.4.3 . Специальные символы

Специальный символ ERE обладает особыми свойствами в определенных контекстах.Вне этих контекстов или когда им предшествует <backslash>, таким символом должен быть ERE, который соответствует самому специальному символу.Специальные символы расширенного регулярного выражения и контексты, в которых они должны иметь свое особое значение, следующие:

.[\(

Тот Самый <period>, <left-square-bracket>, <backslash>, и <left-parenthesis> должно быть специальным, за исключением случаев, когда используется в выражении, заключенном в квадратные скобки (см. RE Выражение, заключенное в квадратные скобки ).Вне выражения, заключенного в квадратные скобки, a <left-parenthesis> сразу же за этим последовал <right-parenthesis> приводит к неопределенным результатам.

То, что вы видите, является результатом вызова неопределенного поведения - все идет своим чередом.

Если вы хотите получить надежные, переносимые результаты, вам придется исключить пустое '()- обозначения.

Другие советы

Если вы перебираете все совпадения и не получаете [3,6) и [0,6), тогда есть ошибка. Я не уверен, какой мандат posix соответствует порядку, в котором возвращаются совпадения.

Попробуйте (abc|())xyz - держу пари, что в обоих местах результат будет одинаковым. Я могу только предположить, что версия C пытается соответствовать xyz везде, где может, и если это не удается, она пытается сопоставить abcxyz везде, где это возможно (но, как вы видите, это не дает сбоя, поэтому мы никогда беспокоиться о " abc " part), тогда как awk должен использовать собственный движок регулярных выражений, который работает так, как вы ожидаете.

Ваше регулярное выражение действительно. Я думаю, что проблема либо в том, что а) POSIX не очень ясно понимает, как должно работать регулярное выражение, либо б) <=> не использует регулярные выражения, совместимые со 100% POSIX (возможно, потому что кажется, что OS X поставляется с более оригинальной версией из <=>). Независимо от того, какая это проблема, она, вероятно, вызвана тем, что это в некотором роде крайний случай, и большинство людей не стали бы писать регулярное выражение таким образом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top