Możesz uzyskać dostęp do takich grup przechwytywania:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc
A jeśli jest wiele dopasowań, możesz je powtarzać:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
console.log(match[0])
match = myRegexp.exec(myString);
}
Edycja: 10.09.2019
Jak widać sposób powtarzania wielu meczów nie był zbyt intuicyjny. Doprowadziło to do propozycji String.prototype.matchAll
metody. Oczekuje się, że ta nowa metoda będzie dostępna w specyfikacji ECMAScript 2020 . Daje nam czysty interfejs API i rozwiązuje wiele problemów. Rozpoczęło się na głównych przeglądarkach i silnikach JS jako Chrome 73+ / Node 12+ i Firefox 67+.
Metoda zwraca iterator i jest używana w następujący sposób:
const string = "something format_abc";
const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
const matches = string.matchAll(regexp);
for (const match of matches) {
console.log(match);
console.log(match.index)
}
Gdy zwraca iterator, możemy powiedzieć, że jest leniwy, co jest użyteczne przy obsłudze szczególnie dużej liczby grup przechwytywania lub bardzo dużych ciągów. Ale jeśli potrzebujesz, wynik można łatwo przekształcić w tablicę za pomocą składni rozprzestrzeniania lub Array.from
metody:
function getFirstGroup(regexp, str) {
const array = [...str.matchAll(regexp)];
return array.map(m => m[1]);
}
// or:
function getFirstGroup(regexp, str) {
return Array.from(str.matchAll(regexp), m => m[1]);
}
W międzyczasie, podczas gdy ta propozycja zyskuje szersze poparcie, możesz skorzystać z oficjalnego pakietu shim .
Również wewnętrzne funkcjonowanie metody jest proste. Równoważna implementacja korzystająca z funkcji generatora wyglądałaby następująco:
function* matchAll(str, regexp) {
const flags = regexp.global ? regexp.flags : regexp.flags + "g";
const re = new RegExp(regexp, flags);
let match;
while (match = re.exec(str)) {
yield match;
}
}
Zostanie utworzona kopia oryginalnego wyrażenia regularnego; ma to na celu uniknięcie skutków ubocznych spowodowanych mutacją lastIndex
właściwości podczas przechodzenia przez wiele dopasowań.
Musimy również upewnić się, że wyrażenie regularne ma flagę globalną, aby uniknąć nieskończonej pętli.
Cieszę się również, że w dyskusji nad propozycją przywoływano nawet to pytanie StackOverflow .
var match = myString.match(myRegexp); // alert(match[1])
:?string = string.substring(match.index + match[0].length)
Oto metoda, za pomocą której można uzyskać n- tą grupę przechwytywania dla każdego dopasowania:
źródło
To
\b
nie jest dokładnie to samo. (Działa--format_foo/
, ale nie działaformat_a_b
) Ale chciałem pokazać alternatywę dla twojego wyrażenia, co jest w porządku. Oczywiściematch
połączenie jest ważne.źródło
format_a_b
”, jak to miało miejsce 6 lat temu, i nie pamiętam, co miałem na myśli ... :-) Wydaje mi się, że oznaczało to, że „nie działaa
tylko na przechwytywanie ”, to znaczy. pierwsza część alfabetyczna poformat_
.Jeśli chodzi o powyższe przykłady nawiasów wielokrotnych powyżej, szukałem tutaj odpowiedzi po tym, jak nie otrzymałem tego, czego chciałem:
Po spojrzeniu na nieco skomplikowane wywołania funkcji z while i .push () powyżej, przyszło mi do głowy, że problem można rozwiązać bardzo elegancko za pomocą mystring.replace () zamiast tego (zamiana NIE jest celem, a nawet nie jest zrobiona , CZYSTA, wbudowana opcja wywołania funkcji rekurencyjnej dla drugiego parametru to!):
Po tym nie sądzę, żebym kiedykolwiek używał .match () do prawie niczego więcej.
źródło
Wreszcie znalazłem jeden wiersz kodu, który działał dla mnie dobrze (JS ES6):
Zwróci to:
źródło
replace
Terminologia użyta w tej odpowiedzi:
someString.match(regexPattern)
./format_(.*?)/g
gdzie(.*?)
byłaby dopasowana grupa.) Znajdują się one w dopasowanych wzorach .Opis
Aby uzyskać dostęp do dopasowanych grup , w każdym dopasowanym wzorcu potrzebujesz funkcji lub czegoś podobnego do iteracji po dopasowaniu . Istnieje wiele sposobów, aby to zrobić, jak pokazuje wiele innych odpowiedzi. Większość innych odpowiedzi wykorzystuje pętlę while do iteracji wszystkich dopasowanych wzorców , ale myślę, że wszyscy znamy potencjalne niebezpieczeństwa związane z takim podejściem. Konieczne jest dopasowanie do
new RegExp()
samego wzorca, o którym wspomniano tylko w komentarzu. Wynika to z faktu, że.exec()
metoda zachowuje się podobnie do funkcji generatora - zatrzymuje się za każdym razem, gdy występuje dopasowanie , ale.lastIndex
kontynuuje ją od następnego.exec()
wywołania.Przykłady kodu
Poniżej znajduje się przykład funkcję
searchString
, która zwracaArray
na wszystkich dopasowanych wzorców , gdzie każdymatch
oznaczaArray
ze wszystkie zawierającego grupy dopasowane . Zamiast używać pętli while, podałem przykłady, używając zarównoArray.prototype.map()
funkcji, jak i bardziej wydajnego sposobu - używając zwykłejfor
pętli.Zwięzłe wersje (mniej kodu, więcej cukru syntaktycznego)
Są one mniej wydajne, ponieważ w zasadzie implementują
forEach
pętlę zamiast szybszejfor
pętli.Wersje performanckie (więcej kodu, mniej cukru syntaktycznego)
Muszę jeszcze porównać te alternatywy z poprzednio wymienionymi w innych odpowiedziach, ale wątpię, aby to podejście było mniej wydajne i mniej bezpieczne w przypadku awarii niż inne.
źródło
String#matchAll
(patrz propozycja etapu 3/7 grudnia 2018 r. ), upraszcza dostęp do wszystkich grup w obiekcie dopasowania (pamiętaj, że grupa 0 to całe dopasowanie, podczas gdy kolejne grupy odpowiadają grupom przechwytywania we wzorcu):Ta metoda daje wynik podobny do
Regex.Matches
C #,re.finditer
w Pythonie,preg_match_all
w PHP.Zobacz wersję demonstracyjną JS (przetestowaną w Google Chrome 73.0.3683.67 (oficjalna wersja), beta (64-bit)):
te
console.log([...matches])
pokazyMożesz również uzyskać wartość dopasowania lub określone wartości grupy za pomocą
UWAGA : Zobacz szczegóły zgodności przeglądarki .
źródło
Twoja składnia prawdopodobnie nie jest najlepsza do zachowania. FF / Gecko definiuje RegExp jako rozszerzenie funkcji.
(FF2 poszedł tak daleko
typeof(/pattern/) == 'function'
)Wygląda na to, że jest to specyficzne dla FF - IE, Opery i Chrome - wszystkie zgłaszają wyjątki.
Zamiast tego użyj jednej z metod wcześniej wspomnianych przez innych:
RegExp#exec
lubString#match
.Oferują te same wyniki:
źródło
Nie ma potrzeby wywoływania
exec
metody! Możesz użyć metody „dopasuj” bezpośrednio na łańcuchu. Tylko nie zapomnij nawiasów.Pozycja 0 ma ciąg ze wszystkimi wynikami. Pozycja 1 ma pierwsze dopasowanie w nawiasach, a pozycja 2 ma drugie dopasowanie w nawiasach. Zagnieżdżone nawiasy są trudne, więc uważaj!
źródło
Jedna wkładka, która jest praktyczna tylko wtedy, gdy masz jedną parę nawiasów:
źródło
while (match = myRegex.exec(myStr)) matches.push(match[1])
Za pomocą kodu:
Edycja: Safari 3, jeśli ma to znaczenie.
źródło
Dzięki es2018 możesz teraz używać
String.match()
nazwanych grup, dzięki czemu wyrażenia regularne są bardziej wyraźne w stosunku do tego, co próbował zrobić.i dostaniesz coś takiego
źródło
źródło
Twój kod działa dla mnie (FF3 na Macu), nawet jeśli zgadzam się z PhiLo, że regex powinien być prawdopodobnie:
(Ale oczywiście nie jestem pewien, ponieważ nie znam kontekstu wyrażenia regularnego.)
źródło
źródło
Tak naprawdę nie potrzebujesz jawnej pętli do analizowania wielu dopasowań - przekaż funkcję zastępczą jako drugi argument, jak opisano w
String.prototype.replace(regex, func)
:m0
Argumentem reprezentuje pełną dopasowany podciąg{0}
,{1}
itpm1
reprezentuje pierwszą grupę dopasowanie, czyli część w nawiasach w regex, który jest0
w pierwszym meczu. Iposition
jest indeksem początkowym w ciągu, w którym znaleziono pasującą grupę - w tym przypadku nieużywany.źródło
W kodzie \ 1 reprezentowanym przez pierwszą grupę ([az])
źródło
Rozwiązanie jednoliniowe:
Możesz więc użyć tej metody (musisz użyć / g):
wynik:
źródło
Uzyskaj wszystkie wystąpienia grupy
źródło
Jestem podobny do mnie i chciałbym, aby wyrażenie regularne zwróciło Obiekt taki:
następnie wyciąć funkcję od dołu
źródło
PO PROSTU UŻYJ RegExp. 1 $ ... $ n ta grupa np .:
1. Aby dopasować pierwszą grupę RegExp. 1 USD
jeśli użyjesz 3 grup w wyrażeniach regularnych (uwaga użyj po string.match (regex))
RegExp. 1 USD RegExp. 2 USD RegExp. 3 USD
źródło