Няколко реализации на регулярни изрази се различават една от друга по фини начини, което е източник на много объркване, когато се опитвам да ги използвам.
Повечето от тези разлики включват семантиката, свързана с това дали символът е екраниран или не. Това най-често е проблем със скоби, но може да се отнася за фигурни скоби и други. Това вероятно е следствие от синтаксиса на езика или средата, в която се намира изпълнението. Например, ако символът $
показва име на променлива на някакъв език, може да се очаква, че регулярните изрази, представени на този език, ще изискват екраниране на котвата "край на реда" към \$
или нещо подобно. Но това, което става объркващо в този момент, е как бихте представили действителен знак за долар. Вярвам, че Perl заобикаля това, като опакова регулярен израз в наклонени черти /
.
По подобен начин има екрани за самите конкретни знаци, например непечатаеми знаци като \n
и \t
. След това има сходно изглеждащи общи групи знаци като \d
за цифри, \s
за празно пространство и \w
, за които току-що научих, че покриват долни черти, както и цифри. Открих, че на няколко пъти се опитвах да използвам \a
за "азбучна" група, но това в крайна сметка съвпадаше само с камбанката 0x07.
Съвсем ясно е, че няма просто и еднократно решение за познаване на всички разлики във функциите и синтаксиса, предлагани от безбройните реализации на регулярни изрази там, освен някой да върши цялата упорита работа и да постави резултатите в добре организиран маса. Ето един пример точно за това, но разбира се, че не Не покривам няколко от програмите, които самият аз използвам широко, които включват vim
, sed
, Notepad++, Eclipse и вярвате или не MS Word (поне версия 2010, подозирам, че 2007 също има това, наричат го „заместващи знаци“) също има проста реализация на регулярен израз.
Предполагам, че това, което искам, е да бъда възможно най-мързелив (в известен смисъл), като се опитвам да измисля начин да определям за всяко дадено изпълнение на регулярен израз какви са неговите „изходни настройки“ извън всяко съмнение чрез прилагане на една (или няколко ) заявки.
Мисля, че мога да направя файл, който съдържа тестови случаи, заедно с огромна заявка за регулярен израз, и по някакъв начин да го проектирам така, че еднократното му изпълнение да ми покаже точно какъв синтаксис трябва да използвам впоследствие, без да се съмнявам повече. (за разлика от необходимостта да редактирате файлове и да използвате множество заявки, за да разберете едно и също нещо, което след известно време остарява ужасно).
Ако никой друг не се е опитвал да конструира подобно чудовище, аз може да се заема с тази задача. Ако изобщо е възможно. Възможно ли е това?
Опитах се да измисля пример (просто за да разбера дали EOL anchor е $
или \$
), но във всеки случай трябваше да използвам множество различни заявки за търсене/замяна, за да определя как програмата ще отговори на вход.
Редактиране: Измислих нещо, използвайки прихващане и обратно проследяване. Трябва да поработя върху него още малко.
Актуализация: Е, Notepad++ не прилага оператора ИЛИ, обикновено означаван с тръбата |
. „Заместващите знаци“ на Word също са лош заместител, той няма |
или *
. Доста съм сигурен, че липсата на някой от операторите за регулярен израз (обединение, concat, звезда) означава, че не може да генерира регулярна граматика, така че тези два са изключени.
Мога да създам входен файл като този:
$
*
]
EOL
и заявка
(\$)|(\*)|(\[)|($)
замяна с
escDollar:\1:escStar:\2:escSQBrL:\3:Dollar:\4:
дава резултат от (приемайки, че неекранираните скоби са група, а неекранираната тръба е или)
escDollar:$:escStar::escSQBrL::Dollar::
escDollar::escStar:*:escSQBrL::Dollar::
]escDollar::escStar::escSQBrL::Dollar::
EOLescDollar::escStar::escSQBrL::Dollar::
Изпълних това през vim
. Този изход ще демонстрира единичните знаци, които съответстват на всеки елемент, посочен до него, т.е. екранираният знак за долар се вижда като съвпадащ с действителния знак за долар, а не с неекранирания елемент със знак за долар в края.
Трудно е да се види какво се случва с котвата $
, тъй като тя съответства на нула символа, но не би трябвало да е трудно да се намери решение за това. Освен това не е често срещана грешка. Тези, за които съм особено притеснен, са тръба и скоби и различните скоби. Когато имате 4 различни типа там, има 2^4 комбинации от екранирани и неекранирани версии от тях, които можете да използвате. Пробата и грешката с това е ужасяваща.
Този изход не е твърде труден за анализиране с един поглед и също така е сериозно лесен за обработка като част от скрипт. Единственият очевиден проблем, който остава, е да разберем дали скобите и тръбата трябва да бъдат избягани. Защото от тях зависи функционалността на цялото нещо.
Изглежда, че това ще изисква множество заявки. Може да е възможно с умело проектирана смесица от обратни наклонени черти, скоби и тръби да разберете комбинацията (в края на краищата само 4 възможности) с първоначална заявка, след което да изберете последващата заявка за генератор на матрици въз основа на нея.
Нещо като това показва, че може да работи:
(e)
(f)
запитване
\((f\))|\|\((e\))
замени с
\1:\2
ще произведе:
:(e
ако екранираните скоби са група, а екранираните канали са или:e)
ако parens е група и екранирана тръба е или(f:
ако екранирани скоби е група и тръба е илиf):
ако parens е група и тръба е или
Все още не ми харесва това, защото изисква втора заявка за втори набор от входни данни. Твърде много настройка. Може просто да направя 4 копия на "матрицата".