Коли регулярне вираження не є регулярним виразом?


9

Оскільки я навчаюсь на моєму курсі офіційного мовного коледжу, я натрапив на ці захоплюючі пости ( One Two ), в яких описано, як знайти просте число за допомогою regexp . Як я вже сказав, регулярний вираз , а не регулярний вираз . Так як регулярний вираз може відповідати рядкам , обчислених кінцевого безліч станів автоматів і знайти просте число , не може бути зроблено з допомогою FSA, регулярний вираз показано в блозі не є повністю регулярним виразом , оскільки вона відступає , щоб відповідати рядку.

Оскільки я ніколи не використовував жодного регулярного вираження, тепер, моє запитання:

Як я можу негайно розпізнати регулярний вираз із "справжнього" регулярного виразу, просто подивившись на нього?

Визначення: Під регулярним виразом я позначаю поняття, визначене в формальних мовах. Під терміном regexp я маю на увазі поняття, підтримуване сучасними мовами програмування; синтаксис regexp часто містить додаткові функції, наприклад, зворотні. Regexps, як видно з мов програмування, є суворо потужнішим, ніж формальні вирази у формальних мовах.


5
Regexp - це лише абревіатура регулярного вираження. Розрахунок простих чисел базується на злому Perl, а не на регулярних виразах.

1
Це досить просто. Звичайні мови використовують конкатенацію, повторення та чергування. Кожен раз, коли двигун підтримує щось не рівнозначне цьому, це не є регулярним.
Кіліан Фот

1
Пов'язані запитання: 1 , 2 , 3 .
Рафаель

@Yannis Якщо ви перестрибнете через паркан до CS, це вже не так. Regexps, як це видно в мовах програмування, суворо потужніше, ніж (формальні мови стилю) регулярні вирази, а коротка форма "regexp" за умовою (я не знаю, наскільки вона поширена) використовується для першого, а не для останнього. добрий.
Рафаель

@KilianFoth Це, правда, не є корисним описом. Наприклад, ви можете додати заперечення (або, справді, будь-який кінцевий набір булевих сполучників) до регулярних виразів, не збільшуючи їх потужність.
Девід Річербі

Відповіді:


13

tl; dr backrefs.

Як тільки в \1регулярному вираженні з'являється (або будь-яке число, яке не використовується для виходу Unicode), це не є регулярним виразом.

Backrefs дозволяє вам зіставляти (a+)b\1відповідність n разів, aа потім b, а потім n разів aдля будь-якого n> 1. Це не звичайна мова (це дитина-постер з незвичної мови).

Необхідно і майже достатньо, щоб backref посилався на групу, яка містить регулярний вираз, який відповідає довільно довгим рядкам або що містить *або +. Єдиний виняток (який я знайшов) з регулярним виразком форми, (A)B\1де A є кінцевою мовою (може бути замінено перерахуванням усіх слів, які їх приймають). Ви можете конвертувати його в word1+Bword1|word2+Bword2ін., Оскільки A кінцевий.

Оглядові групи не знімають регулярність регулярного виразу. A(?=B)C- це поперечний переріз регулярних виразів, AB.*а ACпереріз двох звичайних мов є регулярним. Негативний пошук є подібним, за винятком використання доповнення B.*(доповнення звичайних мов, що є регулярними). Зовнішній вигляд точно такий же, як і A(?<=B)Cпереріз ACі .*BC.


Це необхідно і достатньо? Мені здається (a)\1, що при використанні backref рівнозначно aaі, таким чином, тривіально регулярно. Мені також цікаво, чи можна використовувати твердження lookahead для розпізнавання нерегулярних мов.
MSalters

1
@MSalters: Якщо ви хочете отримати справді технічний, (a)\1це не регулярний вираз, але розпізнає звичайну мову.
Йорг W Міттаг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.