премахване на излишък от регулярен израз с множество възможни разделители

Имам регулярен израз, в който същите критерии за съвпадение могат да се прилагат за множество разделители. [], () и <> са валидни. За примерни цели изглежда така:

\[.\]|\(.\)|<.>

Има ли някакъв начин да се премахне излишъкът от горния регулярен израз? Критериите за съвпадение вътре в разделителите винаги са еднакви, но самите разделители може да са различни.


person user1721663    schedule 05.10.2012    source източник


Отговори (2)


Предполагам, че питате, защото

[[(<].[])>]

не е достатъчно точен по очевидни причини.

Винаги е опасно да отговорите „Не, няма начин“, защото е трудно да сте сигурни, че сте проверили всеки възможен начин. Човек често трябва да измисли солидно доказателство, за да отговори в такива случаи.

Не съм сигурен, че това е достатъчно силно доказателство или дори „доказателство“ изобщо, но помислете за тази (псевдо-) гледна точка на теорията на информацията:

  1. Самата машина на PCRE не познава никаква връзка между двойките знаци [], () и <>. Следователно самият израз трябва да съдържа тази информация, т.е. изисква поне да присъстват шестте знака []()<>.

  2. Не само това, но по същата причина самият израз трябва да дефинира поне две сдвоявания (като третото остава да се подразбира). Не съм сигурен как да докажа, че два оператора за редуване (|) е най-доброто, което можете да направите, но искам да кажа, че дори да има по-компактен начин, ще спестите един знак най-много, тъй като е необходим поне един бит, за да се каже, "Съществуват двойки!"

  3. Екранирането на мета-символите може да бъде уплътнено само от факта, че []() може да се появи в класовете на символи, без да бъде екраниран, но първо, това всъщност не е „премахване на излишък“, колкото е „щастливо обстоятелство в синтаксиса“ , и второ, все още трябва да добавите два знака за дефиницията на споменатия клас знаци: [].

  4. Следователно, моето убеждение е, че дори от теоретична гледна точка, ако моите презумпции за това какво машина за регулярни изрази не може да знае са верни, тогава човек може да спести най-много три знака от регулярен израз, който вече сте предоставили: \[.\]|\(.\)|<.>.

С нетърпение очаквам да бъда коригиран от гурутата на регулярните изрази!

person slackwing    schedule 05.10.2012

Ако наистина използвате PCRE библиотека (чрез PHP, например), можете да използвате група DEFINE за да създадете подпрограма, така:

'~(?(DEFINE)(?<content>\w+))(?:<(?&content)>|\[(?&content)\]|\((?&content)\))~'

...или по-четливо:

(?(DEFINE)(?<content>\w+))
(?:
  <(?&content)>
  |
  \[(?&content)\]
  |
  \((?&content)\)
)

Ето демо в PHP. Трябва да работи и в Perl.

person Alan Moore    schedule 05.10.2012