Próbuję przeanalizować następujący rodzaj ciągu:
[key:"val" key2:"val2"]
gdzie w środku znajduje się dowolny klucz: pary „val”. Chcę pobrać nazwę klucza i wartość. Dla ciekawskich próbuję przeanalizować format bazy danych wojownika zadaniowego.
Oto mój ciąg testowy:
[description:"aoeu" uuid:"123sth"]
co ma na celu podkreślenie, że w kluczu lub wartości może znajdować się wszystko poza spacją, bez spacji wokół dwukropków, a wartości są zawsze w cudzysłowach.
W węźle to jest moje wyjście:
[deuteronomy][gatlin][~]$ node
> var re = /^\[(?:(.+?):"(.+?)"\s*)+\]$/g
> re.exec('[description:"aoeu" uuid:"123sth"]');
[ '[description:"aoeu" uuid:"123sth"]',
'uuid',
'123sth',
index: 0,
input: '[description:"aoeu" uuid:"123sth"]' ]
Ale description:"aoeu"
również pasuje do tego wzorca. Jak mogę odzyskać wszystkie mecze?
javascript
regex
regex-group
taskwarrior
gatlin
źródło
źródło
"some string".match(/regex/g)
Odpowiedzi:
Kontynuuj sprawdzanie
re.exec(s)
w pętli, aby uzyskać wszystkie dopasowania:Wypróbuj z tym JSFiddle: https://jsfiddle.net/7yS2V/
źródło
while
zamiastdo … while
?while(m = re.exec(s))
, co jest anty-wzorcową IMO, albo musisz napisaćm = re.exec(s); while (m) { ... m = re.exec(s); }
. Wolędo ... if ... while
idiom, ale inne techniki też się sprawdzą.g
ustawioną flagę, w przeciwnym razie wewnętrzny wskaźnik nie zostanie przesunięty do przodu. Dokumenty .str.match(pattern)
, jeślipattern
ma flagę globalnąg
, zwróci wszystkie dopasowania jako tablicę.Na przykład:
źródło
"All of us except @Emran:emran26, @Raju:raju13 and @Noman:noman42".match(/@(\w+):(\w+)/g)
(które powrócą["@Emran:emran26", "@Raju:raju13", "@Noman:noman42"]
)/@\w/g
lubnew RegExp("@\\w", "g")
Aby zapętlić wszystkie dopasowania, możesz użyć
replace
funkcji:źródło
To jest rozwiązanie
Jest to oparte na odpowiedzi trawnika, ale krócej.
Zauważ, że flaga `g 'musi być ustawiona, aby przesuwać wewnętrzny wskaźnik do przodu przez wywołania.
źródło
zwraca wszystkie dopasowania jako tablicę.
Jeśli z jakiegoś tajemniczego powodu potrzebujesz dodatkowych informacji
exec
, jako alternatywa dla poprzednich odpowiedzi, możesz to zrobić za pomocą funkcji rekurencyjnej zamiast pętli w następujący sposób (która również wygląda fajniej).jak stwierdzono w poprzednich komentarzach, ważne jest, aby
g
na końcu definicji wyrażenia regularnego przesuwać wskaźnik do przodu w każdym wykonaniu.źródło
W końcu zaczynamy widzieć wbudowaną
matchAll
funkcję, zobacz tutaj opis i tabelę zgodności . Wygląda na to, że od maja 2020 roku obsługiwane są przeglądarki Chrome, Edge, Firefox i Node.js (12+), ale nie przeglądarki IE, Safari i Opera. Wygląda na to, że został sporządzony w grudniu 2018 roku więc daj mu trochę czasu, aby dotrzeć do wszystkich przeglądarek, ale wierzę, że się tam dostanie.Funkcja wbudowana
matchAll
jest fajna, ponieważ zwraca iterowalną . Zwraca również grupy przechwytywania dla każdego meczu! Możesz więc robić takie rzeczy jakWydaje się również, że każdy obiekt dopasowania używa tego samego formatu co
match()
. Zatem każdy obiekt jest tablicą grup dopasowywania i przechwytywania, wraz z trzema dodatkowymi właściwościamiindex
,input
, igroups
. A więc wygląda to tak:Więcej informacji na ten temat
matchAll
można znaleźć na stronie Google dla programistów . Dostępne są również wypełnienia / podkładki .źródło
Oparty na funkcji Agusa, ale wolę zwracać tylko wartości dopasowania:
źródło
Iterables są ładniejsze:
Użycie w pętli:
Lub jeśli chcesz mieć tablicę:
źródło
if (m)
powinno byćif (match)
matchAll
Jeśli masz ES9
(To znaczy, jeśli twój system: Chrome, Node.js, Firefox itp. Obsługuje Ecmascript 2019 lub nowszy)
Użyj nowego
yourString.matchAll( /your-regex/ )
.Jeśli nie masz ES9
Jeśli masz starszy system, oto funkcja ułatwiająca kopiowanie i wklejanie
przykład użycia:
wyjścia:
źródło
Oto moja funkcja, aby uzyskać dopasowania:
źródło
Od wersji ES9 istnieje teraz prostszy i lepszy sposób na uzyskanie wszystkich dopasowań wraz z informacjami o grupach przechwytywania i ich indeksie:
Obecnie jest obsługiwany w Chrome, Firefox, Opera. W zależności od tego, kiedy to czytasz, sprawdź ten link, aby zobaczyć aktualne wsparcie.
źródło
g
ilastIndex
powinno zostać zresetowane do 0 przed wywołaniemmatchAll
.Użyj tego...
Zwróci tablicę wszystkich dopasowań ... To będzie działać dobrze ... Ale pamiętaj, że nie będzie uwzględniać grup ... Zwróci tylko pełne dopasowania ...
źródło
Zdecydowanie poleciłbym użycie funkcji String.match () i utworzenie dla niej odpowiedniego RegEx. Mój przykład to lista ciągów, która jest często konieczna podczas skanowania danych wejściowych użytkownika pod kątem słów kluczowych i fraz.
Mam nadzieję że to pomoże!
źródło
To naprawdę nie pomoże w bardziej złożonym problemie, ale i tak to publikuję, ponieważ jest to proste rozwiązanie dla osób, które nie wykonują wyszukiwania globalnego, tak jak Ty.
Uprościłem wyrażenie regularne w odpowiedzi, aby było jaśniejsze (nie jest to rozwiązanie twojego dokładnego problemu).
To wygląda bardziej rozwlekle niż jest z powodu komentarzy, tak to wygląda bez komentarzy
Zwróć uwagę, że wszelkie grupy, które nie pasują, zostaną wymienione w tablicy jako
undefined
wartości.To rozwiązanie wykorzystuje operator rozproszenia ES6 do oczyszczenia tablicy wartości specyficznych dla wyrażenia regularnego. Będziesz musiał uruchomić swój kod przez Babel, jeśli chcesz obsługiwać IE11.
źródło
Oto rozwiązanie jednokreskowe bez pętli while .
Kolejność jest zachowywana na wynikowej liście.
Potencjalne wady są
źródło
Domyślam się, że gdyby istniały przypadki skrajne, takie jak dodatkowe lub brakujące spacje, to wyrażenie z mniejszymi granicami również może być opcją:
Test
RegEx Circuit
jex.im wizualizuje wyrażenia regularne:
źródło
Oto moja odpowiedź:
źródło
str
) ma nieprawidłowy format (za dużo ostrych nawiasów). Bierzesz tylko klucz, a nie wartość. Twój kod zawiera błąd składni i nie jest wykonywany (ostatnie nawiasy). Jeśli odpowiadasz na „stare” pytanie z już zaakceptowaną odpowiedzią, upewnij się, że dodałeś więcej wiedzy i lepszą odpowiedź niż już zaakceptowana. Nie sądzę, że twoja odpowiedź to robi.