#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Co prowadzi wiodący ~
w początkowym wyrażeniu regularnym?
#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Co prowadzi wiodący ~
w początkowym wyrażeniu regularnym?
Odpowiedzi:
W ~
rzeczywistości jest częścią operatora, =~
który wykonuje dopasowanie wyrażenia regularnego łańcucha po lewej stronie do rozszerzonego wyrażenia regularnego po prawej stronie.
[[ "string" =~ pattern ]]
Zauważ, że ciąg powinien być cytowany, a wyrażenie regularne nie powinno być cytowane.
Podobny operator jest używany w języku programowania Perl.
Wyrażenia regularne rozumiane przez bash
są takie same jak te, które GNU grep
rozumie z -E
flagą, tj. Rozszerzony zestaw wyrażeń regularnych.
Trochę nie na temat, ale warto wiedzieć:
W przypadku dopasowania do wyrażenia regularnego zawierającego grupy przechwytujące część ciągu przechwycona przez każdą grupę jest dostępna w BASH_REMATCH
tablicy. Zerowego / pierwsza pozycja w tej tablicy odpowiada się &
w strukturze zastępczej sed
„s polecenia podstawienia (lub $&
Perl), która jest trochę łańcucha, który pasuje do wzorca, natomiast wpisy w indeksie 1 i dalej odpowiada \1
, \2
itp . w sed
strukturze zastępczej (lub $1
, $2
itp Perl), czyli bity dopasowane każdego nawiasach.
Przykład:
string=$( date +%T )
if [[ "$string" =~ ^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]]; then
printf 'Got %s, %s and %s\n' \
"${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi
To może wygenerować
Got 09, 19 and 14
jeśli aktualny czas zdarzy się 09:19:14.
REMATCH
Bit BASH_REMATCH
nazwa macierzy pochodzi od „Dopasowanie wyrażenia regularnego”, czyli „Re-Match”.
W bash
powłokach innych niż Bourne'a można również używać expr
do ograniczonego dopasowywania wyrażeń regularnych (używając tylko podstawowych wyrażeń regularnych).
Mały przykład:
$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123
grep -E
rozumie tylko w systemach GNU i tylko wtedy, gdy jako wzorzec używana jest niecytowana zmienna [[ $var = $pattern ]]
(patrz [[ 'a b' =~ a\sb ]]
vs p='a\sb'; [[ 'a b' =~ $p ]]
). Uważaj również, aby cytowanie powłoki wpłynęło na znaczenie operatorów RE i że niektóre znaki muszą być cytowane dla tokenizacji powłoki, która może wpływać na przetwarzanie RE. [[ '\' =~ [\/] ]]
zwraca false ksh93
ma jeszcze gorsze problemy. Zobacz zsh
(lub bash 3.1), aby uzyskać bardziej rozsądne podejście, w którym cytowanie powłoki i RE jest wyraźnie oddzielone. [
Wbudowane w zsh
i yash
też =~
operator.
off-topic
! +1 (
[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. A może cytowany *
również pasuje? [[ "This is a fine mess." =~ "T.........fin*es*" ]]
.
[[ a =~ .* ]]
lub [[ a =~ '.*' ]]
lub [[ a =~ \.\* ]]
ta sama .*
RE jest przekazywana do =~
operatora. OTH, w bash
, [[ '\' =~ [)] ]]
zwraca błąd, nie wiesz, nie próbując go czy [[ '\' =~ [\)] ]]
meczów? Co powiesz na [[ '\' =~ [\/] ]]
(robi to w ksh93). Co powiesz na c='a-z'; [[ a =~ ["$c"] ]]
(porównaj z =
operatorem)? Zobacz także: [[ '\' =~ [^]"."] ]]
która zwraca fałszywe ... Zauważ, że można zrobić shopt -s compat31
w bash
celu uzyskania zsh
zachowanie.
zsh
/ bash -o compat31
Jest zachowanie przez [[ a =~ '.*' ]]
to również zgodne z [ a '=~' '.*' ]
(do [
implementacji tego wsparcia =~
) lub expr a : '.*'
. OTOH, to nie jest spójne z [[ a = '*' ]]
vs [[ a = * ]]
(ale wtedy globusy są częścią języka powłoki, podczas gdy RE nie są).
Powinieneś przeczytać strony podręcznika bash, w [[ expression ]]
sekcji.
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Krótko mówiąc, =~
jest operatorem, podobnie jak ==
i !=
. Nie ma to nic wspólnego z rzeczywistym wyrażeniem regularnym w ciągu po prawej stronie.
=~
w prawdziwym życiu ...?
man [[ expresssion ]]
i man [[
nic nie zwracaj . help [[
zwraca przydatne informacje - od [[
wewnętrznej komendy bash - ale nie mówi, czy =~
używa podstawowej czy rozszerzonej składni wyrażenia regularnego. ⋯ Cytowany tekst pochodzi ze strony podręcznika użytkownika bash . Zdaję sobie sprawę, że powiedziałeś „czytaj strony podręcznika bash”, ale na początku myślałem, że masz na myśli przeczytanie stron podręcznika bash. W każdym razie man bash
zwraca ogromny plik, który ma 4139 linii (72 strony). Można go przeszukiwać naciskając /▒▒▒
, co wymaga wyrażenia regularnego, którego smak - podobny =~
- nie jest określony.