Dopasowane wyrażenia regularne

21

Twoim zadaniem tutaj jest napisanie dwóch wyrażeń regularnych, z których każde pasuje do drugiego, ale nie pasuje do siebie.

Oba wyrażenia regularne powinny mieć następującą postać:

/pattern/optional-flags

Jest to również forma, w której należy je dopasować.

Najkrótsze rozwiązanie wygrywa. Długość rozwiązania jest liczona jako suma znaków w obu wyrażeniach regularnych, w tym ukośników i flag.

Użyj wybranego standardu składni wyrażenia regularnego lub określ język programowania, jeśli ma to znaczenie.

Baw się dobrze!

GOTO 0
źródło
Czy wyrażenie regularne musi również pasować do ukośników i flag drugiego wyrażenia regularnego?
ProgramFOX,
@ProgramFOX tak, dodałem wiersz, aby to wyjaśnić.
GOTO 0
Czy potrafisz zdefiniować dopasowanie? tzn. czy wyrażenie regularne /a/pasuje abc?
Facet z kapeluszem
2
@TheGuywithTheHat, tak myślę, chyba że wybierzesz język, który nakłada pewne ograniczenia, takie jak konieczność dopasowania całego łańcucha. Czy to dotyczy twojego problemu?
GOTO 0
1
Żeby było jasne: zakładam, że użycie różnych ograniczników (jak dopuszcza np. PHP PCRE) jest niedozwolone? (Tzn. Nie poddaje się /^%/i %^/%)
Peter Taylor

Odpowiedzi:

7

PRCE z modyfikatorem A: 9 znaków

/A$/
/.A/A

Chociaż jest to wariant /modifier$/odpowiedzi Doorknob , myślę, że ta innowacja kwalifikuje ją jako osobną odpowiedź, a nie komentarz do jego: modyfikator ma podwójne zastosowanie. Zamiast być tam tylko po to, by pasował inny regex, kotwica.

Pierwszy regex pasuje do dowolnego łańcucha zakończonego literałem A. Drugi regex dopasowuje dowolny ciąg, którego drugi znak jest dosłowny A, przy użyciu flagi zakotwiczenia na początek.

Demo online

Peter Taylor
źródło
3
Aby pokonać ten problem, wymagane są tylko cztery znaki bez separatora, a ponieważ //pasuje do wszystkiego, co oznacza, że ​​każdy z wyrażeń regularnych może mieć co najwyżej trzy znaki bez separatora. Korzystając z PHP PCRE, istnieje 73339 niedopasowanych wyrażeń regularnych w ramach tego ograniczenia, i pojawia się wyczerpujące sprawdzenie par, których długość jest mniejsza niż 10 (rzędu 32 par zamiast 5,7 par, ponieważ większość z nich to 5 znaków, w tym ograniczniki) to rozwiązanie i żadnych innych. Dlatego twierdzę, że jest optymalny dla tego konkretnego silnika wyrażeń regularnych.
Peter Taylor
18

4 + 6 = wynik 10

Pierwsze wyrażenie:

/i$/

Drugie wyrażenie regularne:

/^.i/i

Brawo za nadużycie flagi! :-P

Pierwszy pasuje do wszystkiego, co kończy się na i(a więc każde wyrażenie regularne z iflagą).

Drugi pasuje do wszystkiego, co ma drugą postać i.

Alternatywna wersja: /i$/gi /g$/i.

Klamka
źródło
3
Inną odmianą byłoby /x.$/i /^.x/dla
paczki
Lub /i$/i/\/$/i
Peter Taylor
Lub /i$/i/i\$/i
Peter Taylor
6

Wyrażenia regularne JavaScript, wynik: 18

Pierwsze wyrażenie:

/^[^a]+$/

Drugie wyrażenie regularne:

/^[^b]+$/

Test JavaScript:

var regex1 = "/^[^a]+$/";
var regex2 = "/^[^b]+$/";
alert(/^[^a]+$/.test(regex2)); // true: regex1 matches regex2
alert(/^[^b]+$/.test(regex1)); // true: regex2 matches regex1
alert(/^[^a]+$/.test(regex1)); // false: regex1 doesn't match regex1
alert(/^[^b]+$/.test(regex2)); // false: regex2 doesn't match regex2

Testuj online: http://jsfiddle.net/99Sx6/

ProgramFOX
źródło
5

Ruby regex, 15

Wyrażenia regularne:

/.{9}/
/^.{06}$/

Liczę tylko postacie ...

Wersja online

r1 = '/.{9}/'
r2 = '/^.{06}$/'

p r1 =~ /^.{06}$/ #0:   r2 matches r1
p r2 =~ /.{9}/    #0:   r1 matches r2
p r1 =~ /.{9}/    #nil: r1 doesn't match r1
p r2 =~ /^.{06}$/ #nil: r2 doesn't match r2
David Herrmann
źródło
5

4 + 6 = 10

Pierwsze wyrażenie:

/i$/

Drugie wyrażenie regularne:

/\/$/i

i$pasuje do czegoś, co kończy się ina drugim. /$pasuje do czegoś, co kończy się /, do pierwszego.

Justin
źródło
2
Kopia komentarza, który zamieściłem w odpowiedzi Doorknob.
Peter Taylor
@PeterTaylor Do tej pory nie zauważył komentarzy. Były to niezależne odkrycia.
Justin
Tak, niezależnie odkryłem również wersję Shiony.
Peter Taylor
3

5 + 5 = 10

Regex # 1:

/0.$/

Regex # 2:

/^.0/

W 0sw obu regexes można zastąpić dowolnym non-metaznaku i regex nadal działa.

0.$dopasowuje wszystko, co jest drugim ostatnim znakiem 0, i ^.0pasuje do wszystkiego, co jest drugim znakiem 0.

Justin
źródło
2
Pierwsza para nie jest poprawnym wyrażeniem regularnym: musisz uciec przed /es. Alternatywą jest duplikat komentarza do odpowiedzi Doorknob.
Peter Taylor
2

Wyrażenia regularne JavaScript, wynik: 13

Pierwsze wyrażenie:

/\d/

Drugie wyrażenie regularne:

/^[^0]+$/

Objaśnienie: pierwsza regex pasuje do wszystkiego, co zawiera cyfrę, a druga regex pasuje do wszystkiego, co nie zawiera 0.

Test JavaScript:

var regex1 = "/\d/";
var regex2 = "/^[^0]+$/";
alert(/\d/.test(regex2)); // true: regex1 matches regex2
alert(/^[^0]+$/.test(regex1)); // true: regex2 matches regex1
alert(/\d/.test(regex1)); // false: regex1 doesn't match regex1
alert(/^[^0]+$/.test(regex2)); // false: regex2 doesn't math regex2

Testuj online: http://jsfiddle.net/5VYjC/1/

ProgramFOX
źródło
2

12 znaków ;) Wyrażenie regularne JS

/\d/
/0?\/$/g
Andrew Templeton
źródło
2

Wynik: 5 + 5 = 10

Zajęło mi to pół godziny, żeby to rozgryźć, ale bardzo się cieszę, że to zrobiłem :)

1. to: /j.$/

2 miejsce to: /^.j/

1. pasował do jwystępującego na drugiej pozycji, zaczynając od prawej. Drugi odpowiada jwystępowaniu na drugiej pozycji, zaczynając od lewej.

Nie testowałem, ale myślę, że te RegExy są naprawdę wszechstronne, ponieważ jmożna je zastąpić dowolną \wpostacią (lub więcej?) I nadal powinny działać dobrze.

PS Powinno to (miejmy nadzieję) działać w dowolnym języku. Jeśli jednak to nie działa, prosimy o informację w komentarzach poniżej :)

Test

Gaurang Tandon
źródło
I zorientowałem się, że @Quiccunx opublikował już tę samą wersję co moja. Bardzo mi przykro z powodu Quiccunx i jeśli to się spodoba, usunę moją odpowiedź.
Gaurang Tandon
1

PCRE przy użyciu modyfikatora x: 11 znaków

/\s/
/ s.$/x

Pierwszy pasuje do dowolnego łańcucha ze znakiem białych znaków, ale nie zawiera białych znaków. Drugi zawiera białe znaki, ale jest ignorowany z powodu xmodyfikatora; pasuje do każdego ciągu, którego przedostatni charakter jest s.

PCRE i inne silniki wykorzystujące klasy postaci: 11 znaków

/\w+w/
/\Ww/

Pierwszy dopasowuje dowolny ciąg znaków ze znakiem „słowa” (litera, cyfra, znak podkreślenia), po którym następuje literał w; drugi pasuje do dowolnego łańcucha ze znakiem innym niż słowo, po którym następuje literał w.

PCRE i inne silniki wykorzystujące klasy znaków i zakotwiczenie granicy słów: 11 znaków

/\w\w/
/\bw/

Pierwszy dopasowuje dowolny ciąg znaków z dwoma kolejnymi znakami „słownymi”; drugi dowolny ciąg ze znakiem innym niż słowo lub początek ciągu, po którym następuje literał w.

Peter Taylor
źródło
-1

ECMAScript (11 bajtów):

/^\1?d/
/\d/

Inne silniki REGEXP (14 bajtów):

/^\\\\1?d/
/\d/

Pierwsze mecze \ d [..] lub \ 1d [..].

Drugi dopasowuje dowolny ciąg z liczbą.

EDYTOWAĆ:

Oryginalnie ta odpowiedź została opublikowana jako zgodna ze wszystkimi silnikami, ale okazała się błędna.

Wystąpił problem z odniesieniami do grup przechwytywania (na przykład w php).

Ismael Miguel
źródło
Wiele silników wyrażeń regularnych przyjmuje wyrażenia regularne bez otaczających je ukośników, ale pytanie jest dość jasne, wymagając ich policzenia.
Peter Taylor
Nie liczę tego jako odpowiedzi. Dodaję do tego notatkę.
Ismael Miguel
1
@PeterTaylor Dodałem notatkę. Wersja Apache istnieje właśnie dlatego.
Ismael Miguel
Poczekaj: w jakich silnikach analizowany jest pierwszy, który \1nie jest interpretowany jako odniesienie wstecz?
Peter Taylor
W zależności od sposobu korzystania z niego. Na przykład w php, jeśli włożysz do środka "/^\1?d/", będziesz miał problemy, ale jeśli tak '/^\1?d/', to w porządku. Cytaty mają ogromną różnicę przy interpretacji kodu.
Ismael Miguel