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!


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


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.


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/


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

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.


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.


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/



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


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.


-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).


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.