2012-03-21 10 views
65

Tutaj jest wyrażenie regularne stworzyłem używać w JavaScript:Jaka jest różnica między nawiasami kwadratowymi a nawiasami w wyrażeniu regularnym?

var reg_num = /^(7|8|9)\d{9}$/ 

Oto kolejny jeden z sugestią mojego członka zespołu.

var reg_num = /^[7|8|9][\d]{9}$/ 

Zasadą jest, aby zweryfikować numer telefonu:

  • Należy się tylko z dziesięciu cyfr.
  • pierwszy numer ma być dowolny z 7, 8 lub 9.
+13

Twój członek zespołu powinien przeczytać podstawowy samouczek dotyczący wyrażeń regularnych. Druga para nawiasów jest zbędna, a '|' jest błędne - to wyrażenie zweryfikuje ciąg '" | 123456789 "'. –

+0

'[\ d]' jest również śmieszne, użyj '\ d' bezpośrednio. ponieważ '\ d' jest skrótem od' [1234567890] ' – Eddy

Odpowiedz

74

Te regexes są równoważne (dla celów dopasowania)

  • /^(7|8|9)\d{9}$/
  • /^[789]\d{9}$/
  • /^[7-9]\d{9}$/

Wyjaśnienie:

  • (a|b|c) jest wyrażenie "lub" oznacza "A, B lub C", mimo że obecność klamer konieczne dla OR, również przechwytuje cyfry. Aby zachować ścisły odpowiednik, należy zakodować (?:7|8|9), aby utworzyć grupę przechwytującą non.

  • [abc] jest "grupa postać" oznacza, że ​​"każdy znak z A, B lub C" (klasa postaci można użyć zakresów np [a-d] = [abcd])

Przyczyną tych Wyrażenia regularne są zbliżone jest to, że klasa znaków jest skrótem dla "lub" (ale tylko dla pojedynczych znaków). Alternatywnie możesz też zrobić coś takiego, jak (abc|def), które nie jest tłumaczone na klasę postaci.

+24

' '(7 | 8 | 9)' i '[789]' nie są równoważne, ponieważ pierwsze jest przechwytywanie, drugie nie. '(?: 7 | 8 | 9)' byłoby równoważne z drugiej strony (domyślam się, że oczywiście ...). – hochl

+0

Widzę to wyrażenie regularne: '[<<|>> | \] \] | \ [\ []'. Z powodu kontekstu wiem, że regex próbuje dopasować '<<' or '>>' lub '[[' lub ']]'. Ale z tego, co powiedziałeś, powinno pasować '<' or '>' lub '[' lub ']'. Jeśli używasz '|' między '[]', czy nawiasy zachowują się inaczej? –

+1

@DanielKaplan nie używaj '|' w klasie znaków' [...] ', chyba że chcesz dopasować samą postać potoku. Również powielanie znaków w klasie znaków nie ma żadnego efektu - klasa postaci jest listą znaków i dopasuje dokładnie jeden z nich. Domyślam się, że potrzebujesz grupy *, która używa normalnych nawiasów okrągłych: '(<<|>> | \] \] | \ [\ [)' – Bohemian

8

Pierwsze 2 przykłady działają bardzo różnie, jeśli WYMIENIĄ je przez coś. Jeśli pasujesz do tego:

str = str.replace(/^(7|8|9)/ig,''); 

Zamień 7 lub 8 lub 9 na pusty ciąg.

Jeśli pasuje na tej

str = str.replace(/^[7|8|9]/ig,''); 

można zastąpić 7 lub 8 lub 9 LUB pionowy pasek !!!! przez pusty ciąg.

Po prostu znalazłem to na własnej skórze.

+3

Witaj w SO! Zastąpienie lub dopasowanie, to po prostu nie tak. Wielu ludzi popełnia tę pomyłkę i zwykle im to wychodzi - czasami przez lata - ponieważ ich ciągi wejściowe nigdy nie zawierają rury ('|'). –

40

Twoja rada zespołu to: prawie prawo, z wyjątkiem błędu, który popełnił. Gdy już dowiesz się dlaczego, nigdy tego nie zapomnisz. Spójrz na ten błąd.

/^(7|8|9)\d{9}$/ 

Co to robi:

  • ^ i $ oznacza zakotwiczonych mecze, które twierdzi, że podciąg wzorca pomiędzy tymi kotwicami są cały mecz. Łańcuch będzie zgodny tylko wtedy, gdy podtekst dopasuje się do całości, a nie tylko do sekcji.
  • () oznacza grupę przechwytującą przechwytującą.
  • 7|8|9 oznacza dopasowanie jednego z następujących: 7, 8 lub 9. Robi to z zmianami, co robi operator rury | - na zmianę naprzemiennie. To przejście między zmianami: Jeśli pierwsza zmiana nie jest zgodna, silnik musi powrócić przed przesunięciem wskaźnika w trakcie dopasowania naprzemiennego, aby kontynuować dopasowywanie następnej zmiany; Natomiast klasa znaków może postępować sekwencyjnie. Zobacz ten mecz na regex silnika z optymalizacje niepełnosprawnych:
Pattern: (r|f)at 
Match string: carat 

alternations

Pattern: [rf]at 
Match string: carat 

class

  • \d{9} odpowiada dziewięciu cyfr. \d to skrót metaznaku, który dopasowuje dowolne cyfry.
/^[7|8|9][\d]{9}$/ 

Spójrz na to, co robi:

  • ^ i $ oznacza zakotwiczonych mecze, jak również.
  • [7|8|9] to klasa postaci. Dowolne znaki z listy mogą być dopasowane, dlatego | zostało dodane niepoprawnie. Dopasowuje się bez cofania.
  • [\d] to klasa znaków, która zamieszkuje metaznak \d. Połączenie użycia klasy znaków i pojedynczego metaznaku jest przy okazji kiepskim pomysłem, ponieważ warstwa abstrakcji może spowolnić dopasowanie, ale jest to tylko szczegół implementacji i dotyczy tylko kilku implementacji regex. JavaScript nie jest jednym, ale sprawia, że ​​subpattern jest nieco dłuższy.
  • {9} oznacza, że ​​poprzednia pojedyncza konstrukcja powtarza się w sumie dziewięć razy.

Optymalny regex jest /^[789]\d{9}$/, ponieważ /^(7|8|9)\d{9}$/ przechwytuje niepotrzebnie który nakłada spadek wydajności w większości implementacji regex ( stanie się jednym, biorąc pod uwagę kwestia używa słowa kluczowego var w kodzie, to prawdopodobnie jest JavaScript). Użycie funkcji , która działa na komputerze PCRE w celu dopasowania wstępnego, zoptymalizuje brak śledzenia wstecznego, ale nie jesteśmy też w PHP, więc używanie klas [] zamiast na przemian | daje premię wydajnościową, ponieważ mecz nie cofa się, a zatem oba mecze i nie działa szybciej niż przy użyciu poprzedniego wyrażenia regularnego.

+1

po prostu nie interesuje, z jakiego programu pochodzi ten zrzut ekranu? –

+5

http://regex101.com – Unihedron

Powiązane problemy