Chcę tylko utworzyć wyrażenie regularne z dowolnego możliwego ciągu.
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
Czy istnieje do tego wbudowana metoda? Jeśli nie, z czego korzystają ludzie? Ruby ma RegExp.escape
. Nie wydaje mi się, żebym musiał pisać własne, musi być coś standardowego. Dzięki!
javascript
regex
Lance Pollard
źródło
źródło
RegExp.escape
obecnie pracujemy, a każdy, kto uważa, że mają cenny wkład, jest bardzo mile widziany. Core-js i inne wypełniacze to oferują.Odpowiedzi:
Funkcja powiązana powyżej jest niewystarczająca. Nie można uciec
^
lub$
(początek i koniec łańcucha), lub-
, który w grupie znaków jest używany dla zakresów.Użyj tej funkcji:
Choć na pierwszy rzut oka może się to wydawać niepotrzebne, funkcja zmiany znaczenia
-
(a także^
) sprawia, że funkcja ta jest odpowiednia do wstawiania znaków do klasy znaków, a także treści wyrażenia regularnego./
Funkcja Escaping sprawia, że funkcja jest odpowiednia do zmiany znaczenia znaków i może być używana w dosłownym wyrażeniu regularnym JS do późniejszej ewaluacji.Ponieważ nie ma żadnej wady ucieczki od któregoś z nich, sensowne jest ucieczka, aby objąć szersze przypadki użycia.
I tak, rozczarowujące jest to, że nie jest to część standardowego JavaScript.
źródło
/
w ogólequotemeta
(\Q
), Pythonre.escape
, PHPpreg_quote
, RubyRegexp.quote
...var e = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g;
a następnie twoją funkcją jest Wreturn s.replace(e, '\\$&');
ten sposób tworzysz RegExp tylko raz.RegExp.escape
której implementacja różni się od twojej? Czy nie byłoby lepiej, gdyby ta funkcja nie była do niczego dołączona?Dla każdego, kto za pomocą lodash, ponieważ v3.0.0 _.escapeRegExp funkcją jest wbudowany w:
W przypadku, gdy nie chcesz wymagać pełnej biblioteki lodash, możesz potrzebować tylko tej funkcji !
źródło
escapeRegExp
funkcji.Większość wyrażeń tutaj rozwiązuje pojedyncze przypadki użycia.
W porządku, ale wolę podejście „zawsze działa”.
Spowoduje to „całkowite uniknięcie” literału dla dowolnego z poniższych zastosowań w wyrażeniach regularnych:
new RegExp(regExpEscape(str))
new RegExp('[' + regExpEscape(str) + ']')
new RegExp('x{1,' + regExpEscape(str) + '}')
Objęte znaki specjalne:
-
: Tworzy zakres znaków w klasie znaków.[
/]
: Zaczyna / kończy klasę znaków.{
/}
: Uruchamia / kończy specyfikator numeracji.(
/)
: Zaczyna / kończy grupę.*
/+
/?
: Określa typ powtarzania..
: Pasuje do dowolnej postaci.\
: Ucieka znaki i uruchamia byty.^
: Określa początek pasującej strefy i neguje dopasowanie w klasie znaków.$
: Określa koniec pasującej strefy.|
: Określa naprzemienność.#
: Określa komentarz w trybie wolnych odstępów.\s
: Ignorowane w trybie swobodnych odstępów.,
: Oddziela wartości w specyfikatorze numeracji./
: Rozpoczyna lub kończy wyrażenie.:
: Uzupełnia specjalne typy grup i część klas postaci w stylu Perla.!
: Neguje grupę o zerowej szerokości.<
/=
: Część specyfikacji grupy o zerowej szerokości.Uwagi:
/
nie jest absolutnie konieczne w żadnym smaku wyrażenia regularnego. Jednakże, chroni w przypadku gdy ktoś (Dreszcz) robieval("/" + pattern + "/");
.,
zapewnia, że jeśli ciąg ma być liczbą całkowitą w specyfikatorze liczbowym, poprawnie spowoduje błąd kompilacji RegExp zamiast kompilacji po cichu niepoprawnej.#
i\s
nie trzeba zmieniać znaczenia w JavaScript, ale w wielu innych odmianach. Są one tutaj usuwane na wypadek, gdyby wyrażenie regularne zostało później przekazane do innego programu.Jeśli potrzebujesz również w przyszłości zabezpieczyć wyrażenie regularne przed potencjalnymi dodatkami do możliwości silnika regex JavaScript, zalecam użycie bardziej paranoicznej:
Ta funkcja unika każdego znaku z wyjątkiem tych, które wyraźnie gwarantują, że nie zostaną użyte w składni w przyszłych smakach wyrażeń regularnych.
Jeśli naprawdę zależy Ci na higienie, rozważ ten przypadek:
To powinno dobrze skompilować się w JavaScript, ale nie będzie w innych smakach. Jeśli zamierzasz przejść do innego smaku, zerowy przypadek
s === ''
powinien być niezależnie sprawdzony, tak jak:źródło
/
Nie musi być uciekł w[...]
klasy postaci.Przewodnik po wyrażeniach regularnych Mozilla Developer Network udostępnia tę funkcję zmiany znaczenia:
źródło
=
nie jest już uwzględniona.W widżecie autouzupełniania jQueryUI (wersja 1.9.1) używają nieco innego wyrażenia regularnego (wiersz 6753), oto wyrażenie regularne połączone z podejściem @bobince.
źródło
,
(co nie jest metaznakiem), i#
białe znaki, które mają znaczenie tylko w trybie swobodnych odstępów (który nie jest obsługiwany przez JavaScript). Jednak mają rację, aby nie uciec przed ukośnikiem.$.ui.autocomplete.escapeRegex(myString)
.Nic nie powinno powstrzymywać Cię przed ucieczką od każdego niealfanumerycznego znaku:
Tracisz przy tym pewien stopień czytelności,
re.toString()
ale zyskujesz dużą prostotę (i bezpieczeństwo).Zgodnie z ECMA-262, z jednej strony, regularne wyrażenie „znaków składniowe” są zawsze niealfanumeryczne tak, że wynik jest bezpieczna, a szczególne sekwencje (
\d
,\w
,\n
) są zawsze alfanumeryczny takie, że żadne fałszywe ucieka kontroli będzie produkowany .źródło
.replace(/[^\w]/g, '\\$&')
działałoby to w ten sam sposób.new RegExp('🍎'.replace(/(?=\W)/g, '\\'), 'u')
zgłasza wyjątek, ponieważ\W
dopasowuje każdą jednostkę kodu pary zastępczej osobno, co powoduje nieprawidłowe kody ucieczki..replace(/\W/g, "\\$&");
Propozycję ES7 dotyczącą RegExp.escape można znaleźć na stronie https://github.com/benjamingr/RexExp.escape/ , a polifill jest dostępny na stronie https://github.com/ljharb/regexp.escape .
źródło
To jest krótsza wersja.
Obejmuje to non-meta znaków
%
,&
,'
oraz,
, ale specyfikacja JavaScript RegExp pozwala na to.źródło
.
brakuje. I()
… Albo nie?[-^
jest dziwny. Nie pamiętam co tam jest.XRegExp ma funkcję ucieczki:
XRegExp.escape('Escaped? <.>'); // -> 'Escaped\?\ <\.>'
Więcej na: http://xregexp.com/api/#escape
źródło
Zamiast tylko uciekających znaków, które spowodują problemy w wyrażeniu regularnym (np. Czarna lista), dlaczego nie rozważyć użycia białej listy. W ten sposób każda postać jest uważana za skażoną, chyba że pasuje.
W tym przykładzie przyjmij następujące wyrażenie:
Ta biała lista zawiera litery, cyfry i spacje:
Zwroty:
Może to oznaczać ucieczkę postaci, które nie wymagają ucieczki, ale nie przeszkadza to w wyrażeniu (być może niewielkie kary czasowe - ale warto dla bezpieczeństwa).
źródło
źródło
Funkcje w pozostałych odpowiedziach są nadmiernie zblokowane, aby uciec przed całymi wyrażeniami regularnymi (mogą być przydatne do ucieczki części wyrażeń regularnych, które później zostaną połączone w większe wyrażenia regularne).
Jeśli ucieczka całego wyrażenia regularnego i są z nim zrobić, cytując metaznaków które są albo samodzielnym (
.
,?
,+
,*
,^
,$
,|
,\
) lub uruchomić coś ((
,[
,{
) to wszystko, czego potrzebujesz:I tak, to rozczarowujące, że JavaScript nie ma takiej funkcji jak ta wbudowana.
źródło
(text)next
i wstawiasz je:(?:
+ input +)
. Twoja metoda da wynikowy ciąg,(?:\(text)next)
który się nie skompiluje. Zauważ, że jest to całkiem rozsądne wstawienie, a nie jakieś szalone, takie jakre\
+ input +re
(w tym przypadku programistę można obwiniać za zrobienie czegoś głupiego)\
należy go uciec, ponieważ wyrażenie regularne pozostanie\w
nienaruszone. Poza tym JavaScript wydaje się nie pozwalać na śledzenie)
, przynajmniej w tym przypadku Firefox zgłasza błąd.)
Innym (znacznie bezpieczniejszym) podejściem jest ucieczka od wszystkich znaków (a nie tylko kilku specjalnych, które obecnie znamy) przy użyciu formatu unikodu
\u{code}
:Pamiętaj, że musisz przekazać
u
flagę, aby ta metoda działała:źródło
Dotychczas istniało i będzie 12 znaków meta, które należy uciec,
aby uznać je za dosłowne.
Nie ma znaczenia, co się dzieje z ciągiem znaków ucieczki, wstawionym do zbalansowanego
wyrażenia regularnego, dołączonym, nie ma znaczenia.
Wykonaj zamianę ciągu za pomocą tego
źródło
]
?