Za pomocą https://regex101.com/ zbudowałem wyrażenie regularne, aby zwrócić pierwsze wystąpienie adresu IP w ciągu.
RegExp:
(?:\d{1,3}\.)+(?:\d{1,3})
RegExp, w tym ograniczniki:
/(?:\d{1,3}\.)+(?:\d{1,3})/
Z następującym ciągiem testowym:
eu-west 140.243.64.99
Zwraca pełne dopasowanie:
140.243.64.99
Bez względu na to, co spróbuję z kotwicami itp. Poniższy skrypt bash nie będzie działał z wygenerowanym wyrażeniem regularnym.
temp="eu-west 140.243.64.99 "
regexp="(?:\d{1,3}\.)+(?:\d{1,3})"
if [[ $temp =~ $regexp ]]; then
echo "found a match"
else
echo "No IP address returned"
fi
bash
regular-expression
rjm61
źródło
źródło
=~
Operator jest omówione tutaj w instrukcji , gdzie jest napisane bash używa „rozszerzonych wyrażeń regularnych”. Rozszerzone wyrażenia regularne są opisane naregex(7)
stronie podręcznika i krótko streszczone tutaj .Odpowiedzi:
\d
to niestandardowy sposób wymawiania „dowolnej cyfry”. Myślę, że pochodzi z Perla, a wiele innych języków i narzędzi obsługuje również RE-y kompatybilne z Perlem (PCRE). (i np. GNU grep 2.27 w wersji Debian obsługuje podobne\w
znaki dla słów, nawet w trybie normalnym).Bash nie obsługuje
\d
jednak, więc musisz jawnie użyć[0-9]
lub[[:digit:]]
. To samo dla grupy nie przechwytującej(?:..)
, użyj tylko(..)
zamiast tego.To powinno wydrukować
match
:źródło
grep
obsługuje\d
bez-P
?\w
i\b
, czego nauczyłem się od Perla, więc się pomyliłem.\d
czy PCRE są „niestandardowe”. Są dość standardowe, różnią się od oryginalnych wyrażeń regularnych i rozszerzonych wyrażeń regularnych.\d
. Chociaż masz rację, że PCRE są raczej standardowe lub najmniej zdefiniowane. Irytujące jest to, że problem GNU grep (lub glibc) obsługuje niektóre PCRE podobny węgla, co najmniej\w
, a\s
przy interpretacji ERE, w tym kontekście, że bardzo dużo jest nietypowa. Moje frazowanie może częściowo wynikać z tego, a także z błędnego zbierania danych, które\d
podobnie było wspierane przez GNU.(:...)
i\d
są operatorami wyrażeń regularnych perl lub PCRE (jak w GNUgrep -P
).bash
obsługuje tylko rozszerzone wyrażenia regularne, zgrep -E
wyjątkiem tego, że dla wyrażeń regularnych przekazywanych dosłownie tak jak w[[ text =~ regexp-here ]]
przeciwieństwie do w wyniku niecytowanego rozszerzenia (jak w[[ text =~ $var ]]
lub[[ test =~ $(printf '%s\n' 'regexp-here') ]]
), jest ograniczony do zestawu funkcji rozszerzonego wyrażenia regularnego POSIX.Więc nawet w systemach, w których
grep -E '\d'
działałoby (GNU ERE zaimportowały już niektóre rozszerzenia z wyrażeń regularnych w Perlu,\s
tak jak w przyszłych wersjach\d
), należy użyć:w
bash
go do pracy ([[ $text =~ \d ]]
nie będzie).W przypadku powłoki obsługującej PCRE możesz
zsh
zamiast tego użyć :ksh93 obsługuje również własną implementację wyrażeń regularnych podobnych do perla (nie w pełni kompatybilnych) jako część dopasowania wzorca. Tam użyłbyś:
(zwróć uwagę na
=
zamiast=~
. Będziesz chciał użyć zmiennych tymczasowych, ponieważ jest bardzo błędny, gdy tego nie robisz)źródło
Witryna regex101.com używa PCRE (spójrz w lewy górny róg) jako domyślnej i brakuje jej obsługi składni wyrażenia regularnego „Extended”. To są „regularne wyrażenia zgodne z Perlem”, które pochodzą (jak można tego oczekiwać) od Perla.
PCRE jest wspierany przez niektóre narzędzia (jak
grep -P
) pod pewnymi warunkami, ale obsługa wyrażeń regularnych bash wewnątrz tego[[…]]
idiomu jest tylko dla rozszerzonych wyrażeń regularnych (jakgrep -E
).W rozszerzonym wyrażeniu regularnym
(?…)
nawias nieprzechwytujący nie istnieje i brakuje również \ d. Musisz użyć prostego(…)
i[0-9]
:źródło