Mam bardzo długie wyrażenie regularne, które chcę podzielić na wiele wierszy w moim kodzie JavaScript, aby każda linia miała długość 80 znaków zgodnie z regułami JSLint. Myślę, że jest po prostu lepszy do czytania. Oto próbka wzoru:
var pattern = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
javascript
regex
jslint
expression
readability
Nik Sumeiko
źródło
źródło
/\S+@\S+\.\S+/
?Odpowiedzi:
Możesz przekonwertować go na ciąg i utworzyć wyrażenie, wywołując
new RegExp()
:Uwagi:
RegExp
akceptuje modyfikatory jako drugi parametr/regex/g
=>new RegExp('regex', 'g')
[ Dodatek ES20xx (otagowany szablon)]
W ES20xx możesz używać otagowanych szablonów . Zobacz fragment.
Uwaga:
\s
,\s+
,\s{1,x}
,\t
,\n
etc).źródło
new RegExp
to świetny sposób na wielowierszowe wyrażenia regularne. Zamiast łączyć tablice, możesz po prostu użyć operatora konkatenacji ciągów:var reg = new RegExp('^([a-' + 'z]+)$','i');
//
) i wkleić go jako argument ciągu do konstruktora RegExp. Dzieje się tak, ponieważ znaki ukośnika odwrotnego są używane podczas oceny literału ciągu . Przykład:/Hey\sthere/
nie można zastąpićnew RegExp("Hey\sthere")
. Zamiast tego powinien zostać zastąpiony przeznew RegExp("Hey\\sthere")
Uwaga na dodatkowy lewy ukośnik! Dlatego wolę po prostu zostawić długi dosłowny regex w jednej długiej liniiRegExp
znacznie łatwiejszy do zrozumienia sposób.Rozszerzając odpowiedź @KooiInc, możesz uniknąć ręcznej zmiany znaczenia każdego znaku specjalnego za pomocą
source
właściwościRegExp
obiektu.Przykład:
lub jeśli chcesz uniknąć powtarzania
.source
właściwości możesz to zrobić za pomocąArray.map()
funkcji:W ES6 funkcję mapy można zredukować do:
.map(r => r.source)
źródło
combineRegex = (...regex) => new RegExp(regex.map(r => r.source).join(""))
combineRegex(/regex1/, /regex2/, ...)
Używanie ciągów w
new RegExp
jest niewygodne, ponieważ musisz uniknąć wszystkich odwrotnych ukośników. Możesz pisać mniejsze wyrażenia regularne i łączyć je.Podzielmy to wyrażenie regularne
Użyjemy funkcji, aby później uczynić rzeczy piękniejszymi
A teraz dajmy czadu
Ponieważ ma to koszt, spróbuj tylko raz zbudować prawdziwe wyrażenie regularne, a następnie użyj go.
źródło
multilineRegExp([/a|b/, /c|d])
wyniki w/a|bc|d/
, a miałeś na myśli(a|b)(c|d)
.Są tutaj dobre odpowiedzi, ale dla kompletności ktoś powinien wspomnieć o podstawowej funkcji dziedziczenia w łańcuchu prototypów w Javascript . Coś takiego ilustruje ten pomysł:
źródło
Dzięki cudownemu światu literałów szablonów możesz teraz pisać duże, wielowierszowe, dobrze skomentowane, a nawet semantycznie zagnieżdżone wyrażenia regularne w ES6.
Korzystając z tego, możesz teraz pisać wyrażenia regularne w ten sposób:
Wyjścia
A co z multiline?
Wyjścia
hel
, schludnie!„A co, jeśli muszę faktycznie przeszukać nową linię?”, A więc użyj
\n
głupiego!Pracuję na moim Firefoksie i Chrome.
Ok, „co powiesz na coś bardziej złożonego?”
Jasne, oto fragment niszczącego parsera JS obiektów, nad którym pracowałem :
Wyprowadza
/^\s*((\})|(?:[,{]\s*)(?:(\.\.\.)|(\b\d+\b|\b[A-Za-z$_][\w$]*\b|("|')(?:(?!\5|\\).|(?:\\.))*\5)\s*(:|)|\s*(?={)))((?:\s*(?:[,}\]=]|$)|\s*\}|\s*[{[:]|\s*[,}{]).*)$/
I uruchomić to z małym demo?
Pomyślnie wyświetla
Zwróć uwagę na pomyślne przechwycenie cytowanego ciągu.
Przetestowałem to na Chrome i Firefox, działa świetnie!
Jeśli jesteś ciekawy, możesz sprawdzić , co robiłem , i jego demonstrację .
Chociaż działa tylko w przeglądarce Chrome, ponieważ Firefox nie obsługuje odwołań wstecznych ani nazwanych grup. Zwróć więc uwagę, że przykład podany w tej odpowiedzi jest w rzeczywistości wersją wykastrowaną i może łatwo zostać oszukany, aby zaakceptować nieprawidłowe ciągi.
źródło
W powyższym wyrażeniu regularnym brakuje niektórych czarnych ukośników, które nie działają poprawnie. Więc zredagowałem wyrażenie regularne. Weź pod uwagę to wyrażenie regularne, które działa 99,99% w przypadku weryfikacji adresu e-mail.
źródło
Aby uniknąć Array
join
, możesz również użyć następującej składni:źródło
Osobiście wybrałbym mniej skomplikowane wyrażenie regularne:
Jasne, jest mniej dokładny niż twój obecny wzorzec, ale co próbujesz osiągnąć? Czy próbujesz wyłapać przypadkowe błędy, które mogą wprowadzić Twoi użytkownicy, czy obawiasz się, że Twoi użytkownicy mogą próbować wprowadzić nieprawidłowe adresy? Jeśli to pierwszy, wybrałbym łatwiejszy wzór. Jeśli to drugie, lepszą opcją może być weryfikacja w odpowiedzi na e-mail wysłany na ten adres.
Jeśli jednak chcesz użyć swojego obecnego wzorca, byłoby (IMO) łatwiejsze do odczytania (i utrzymania!), Budując go z mniejszych wzorców podrzędnych, na przykład:
źródło
Możesz po prostu użyć operacji na łańcuchach.
źródło
Próbowałem ulepszyć odpowiedź korun poprzez hermetyzację wszystkiego i zaimplementowanie wsparcia dla dzielenia grup przechwytywania i zestawów znaków - dzięki czemu ta metoda jest znacznie bardziej wszechstronna.
Aby użyć tego fragmentu, musisz wywołać funkcję wariadyczną,
combineRegex
której argumentami są obiekty wyrażenia regularnego, które musisz połączyć. Jego implementację można znaleźć na dole.Grupy przechwytywania nie mogą być podzielone bezpośrednio w ten sposób, ponieważ pozostawiłoby to tylko jeden nawias. Twoja przeglądarka nie zadziała z wyjątkiem.
Zamiast tego po prostu przekazuję zawartość grupy przechwytywania do tablicy. Nawiasy są dodawane automatycznie po
combineRegex
napotkaniu tablicy.Ponadto kwantyfikatory muszą za czymś podążać. Jeśli z jakiegoś powodu wyrażenie regularne musi zostać podzielone przed kwantyfikatorem, należy dodać parę nawiasów. Zostaną one automatycznie usunięte. Chodzi o to, że pusta grupa przechwytywania jest całkiem bezużyteczna i dlatego kwantyfikatory mają do czego się odwoływać. Tej samej metody można użyć w przypadku grup bez przechwytywania (
/(?:abc)/
staje się[/()?:abc/]
).Najlepiej wyjaśnić to na prostym przykładzie:
stanie się:
Jeśli musisz podzielić zestawy znaków, możesz użyć obiektów (
{"":[regex1, regex2, ...]}
) zamiast tablic ([regex1, regex2, ...]
). Treść klucza może być dowolna, o ile obiekt zawiera tylko jeden klucz. Zauważ, że zamiast tego()
musisz użyć]
jako fikcyjnego początku, jeśli pierwszy znak może być zinterpretowany jako kwantyfikator. To znaczy/[+?]/
staje się{"":[/]+?/]}
Oto fragment i bardziej kompletny przykład:
źródło
Świetna odpowiedź @ Hashbrown poprowadziła mnie na właściwą ścieżkę. Oto moja wersja, również zainspirowana tym blogiem .
Użyj tego w ten sposób:
Aby stworzyć ten
RegExp
obiekt:źródło