Чому деякі команди регулярних виразів мають протилежні інтерпретації '\' з різними символами?


10

Візьмемо, наприклад, цю команду:

find . -regex ".*\.\(cpp\|h\)"

Тут ви знайдете всі файли .h та .cpp у вашому каталозі. Символ періоду "." у регулярних виразах зазвичай означає «будь-який символ». Щоб він відповідав лише фактичному періоду, потрібно уникати його за допомогою символу зворотної косої риски '\'.

У цьому випадку, задавши персонажа з особливим значенням, ви повинні уникати його, щоб отримати фактичний персонаж, який він представляє.

Тепер візьміть круглі дужки та смужку "або", будучи символами '(', ')' та '|' відповідно. Вони також мають особливі значення, які використовуються для групування регулярних виразів. Однак, щоб отримати особливий сенс, символів потрібно уникати за допомогою зворотної косої риси! Без зворотної косої риси символи мають значення фактичного символу, який він представляє.

Чому "." трактуються по-різному від '(', ')' та '|'?

Відповіді:


12

Відповідь справді "просто тому". Існує ціла купа різних синтаксисів регулярних виразів, і хоча вони мають схожий вигляд і зазвичай основи однакові, вони різняться між собою.

Історично кожен інструмент мав свою нову реалізацію, роблячи все, що автор вважав найкращим. Існує рівновага між створенням персонажів спеціальними з і без втечі - занадто багато персонажів, які «природно особливі», і вам в кінцевому підсумку потрібно уникати їх завжди, щоб відповідати їм; або, навпаки, вам потрібна купа шляхів для використання загального синтаксису регулярних виразів, таких як () групування. І кожен, хто пише програму, вирішив, як це зробити, виходячи з потреб того, що відповідає їхній програмі, на тому, що вони вважають правильним підходом та на фазі Місяця.

Існує спроба стандартизації з POSIX, яка визначає " основні регулярні вирази " та " розширені регулярні вирази ". Дивовижно, вони працюють одна від одної у відношенні \- іноді , але не з ідеальною послідовністю.

Регулярні вирази Perl стали ще одним стандартом дефакто з двох причин: по-перше, вони дуже гнучкі та потужні, по-друге, вони насправді досить розумні , з умовами на зразок "\ завжди уникає не буквено-цифрових символів".

У GNU Find є -regextypeопція, де ви можете змінити використаний синтаксис регулярного вираження. На жаль, "perl" - це не варіант, принаймні у версії пошуку, яку я маю. (За замовчуванням GNU, не дивно, "emacs", і цей синтаксис тут задокументований .)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.