#!/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
Was macht das Leading ~
im beginnenden regulären Ausdruck?
#!/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
Was macht das Leading ~
im beginnenden regulären Ausdruck?
Antworten:
Tatsächlich ~
ist The Teil des Operators =~
, der eine Übereinstimmung des Strings mit regulären Ausdrücken links und rechts vom erweiterten regulären Ausdruck ausführt.
[[ "string" =~ pattern ]]
Beachten Sie, dass die Zeichenfolge in Anführungszeichen gesetzt und der reguläre Ausdruck nicht in Anführungszeichen gesetzt werden sollte.
Ein ähnlicher Operator wird in der Programmiersprache Perl verwendet.
Die regulären Ausdrücke, die unter verstanden werden, bash
sind die gleichen, die GNU grep
mit dem -E
Flag versteht, dh die erweiterte Menge regulärer Ausdrücke.
Etwas abseits des Themas, aber gut zu wissen:
Beim Abgleichen mit einem regulären Ausdruck, der Erfassungsgruppen enthält, ist der von jeder Gruppe erfasste Teil der Zeichenfolge im BASH_REMATCH
Array verfügbar . Die nullte / erster Eintrag in dieser Matrix entspricht &
im Ersetzungsmuster sed
‚s Substitutionsbefehls (oder $&
in Perl), welche das Bit des String ist, der das Muster übereinstimmt, während die Einträge mit dem Index 1 und weiter entsprechen \1
, \2
usw. . in einem sed
Ersetzungsmuster (oder $1
, $2
usw. in Perl), dh die von jeder Klammer angepasst Bits.
Beispiel:
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
Dies kann ausgegeben werden
Got 09, 19 and 14
wenn die aktuelle Zeit zufällig 09:19:14 ist.
Das REMATCH
Bit des BASH_REMATCH
Arraynamens stammt von "Regular Expression Match", dh "RE-Match".
In nicht- bash
Bourne-ähnlichen Shells kann auch eine expr
eingeschränkte Übereinstimmung mit regulären Ausdrücken verwendet werden (wobei nur grundlegende reguläre Ausdrücke verwendet werden).
Ein kleines Beispiel:
$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123
grep -E
nur auf GNU-Systemen verstanden wird und nur, wenn eine Variable ohne Anführungszeichen als Muster verwendet wird [[ $var = $pattern ]]
(siehe [[ 'a b' =~ a\sb ]]
vs p='a\sb'; [[ 'a b' =~ $p ]]
). Beachten Sie auch, dass Shell-Anführungszeichen die Bedeutung von RE-Operatoren beeinflussen und dass einige Zeichen für die Shell-Token-Erstellung in Anführungszeichen gesetzt werden müssen, die sich auf die RE-Verarbeitung auswirken können. [[ '\' =~ [\/] ]]
gibt false zurück. ksh93
hat noch schlimmere Probleme. Siehe zsh
(oder Bash 3.1) für einen vernünftigeren Ansatz, bei dem Shell- und RE-Anführungszeichen klar voneinander getrennt sind. Die [
eingebauten zsh
und yash
haben auch einen =~
Operator.
off-topic
! +1 (
[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. Oder stimmt das *
auch mit einem Zitat überein? [[ "This is a fine mess." =~ "T.........fin*es*" ]]
.
[[ a =~ .* ]]
oder [[ a =~ '.*' ]]
oder [[ a =~ \.\* ]]
wird dieselbe .*
RE an den =~
Operator übergeben. OTH, in bash
, [[ '\' =~ [)] ]]
gibt einen Fehler zurück, würden Sie wissen, ohne es zu versuchen, ob [[ '\' =~ [\)] ]]
Übereinstimmungen vorliegen? Wie wäre es [[ '\' =~ [\/] ]]
(tut es in ksh93). Wie wäre es c='a-z'; [[ a =~ ["$c"] ]]
(vergleiche mit dem =
Betreiber)? Siehe auch: [[ '\' =~ [^]"."] ]]
was gibt false zurück ... Beachten Sie, dass Sie tun können , shopt -s compat31
in bash
dem bekommen zsh
Verhalten.
zsh
/ bash -o compat31
‚S Verhalten [[ a =~ '.*' ]]
ist auch im Einklang mit [ a '=~' '.*' ]
(für [
Implementierungen , die Unterstützung =~
) oder expr a : '.*'
. OTOH, es ist nicht konsistent mit [[ a = '*' ]]
vs [[ a = * ]]
(aber dann sind Globs Teil der Shell-Sprache, während REs nicht sind).
Sie sollten die bash-Manpages unter dem [[ expression ]]
Abschnitt lesen .
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)).
Lange Rede kurzer Sinn, =~
ist ein Operator, genau wie ==
und !=
. Es hat nichts mit dem tatsächlichen regulären Ausdruck in der Zeichenfolge zu seiner Rechten zu tun.
=~
...?
man [[ expresssion ]]
und man [[
nichts zurück. help [[
Gibt nützliche Informationen zurück - seit [[
einem internen Bash-Befehl - aber sagt nicht, ob =~
grundlegende oder erweiterte Regex-Syntax verwendet wird. ⋯ Der von Ihnen zitierte Text stammt aus der Bash- Manpage. Mir ist klar, dass Sie gesagt haben: "Lies die Manpages der Bash", aber zuerst dachte ich, Sie wollten die Manpages der Bash lesen. In jedem Fall wird man bash
eine riesige Datei zurückgegeben, die 4139 Zeilen (72 Seiten) lang ist. Es kann durch Drücken von gesucht werden /▒▒▒
, was einen regulären Ausdruck erfordert, dessen Geschmack - wie =~
- nicht spezifiziert ist.