Das ist syntaktisch falsch:
#!/usr/bin/env bash
dimension="4x5"
if [[ "$dimension" !=~ '[0-9]x[0-9]' ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
return 1;
fi
die obige Syntax ist falsch...also meine Frage ist - gibt es eine Möglichkeit,!=~
...ich vermute, es ist !~
? Wenn das stimmt, so viel zu Negationsregeln, lulz. Okay, ich habe es getestet und es !~
funktioniert auch nicht.
Antwort1
Für das Schlüsselwort gibt es keine !=~
Oder- Operatoren . Stattdessen wird das Ergebnis des Vergleichs negiert:!~
[[
[[ ! "string" =~ regex ]]
Zum Zitieren des regex
Arguments heißt es im Handbuch:
Jeder Teil des Musters kann in Anführungszeichen gesetzt werden, um die Übereinstimmung des zitierten Teils als Zeichenfolge zu erzwingen.
Daher sollten Teile von regulären Ausdrücken regex
nicht in Anführungszeichen gesetzt werden – es sei denn, die Shell-Option compat31
ist gesetzt:
shopt
...compat31
Wenn gesetzt, ändert bash sein Verhalten in Bezug auf zitierte Argumente des Operators
[[
des bedingten Befehls auf das der Version 3.1=~
Versuchen Sie für das angegebene Beispiel:
if [[ ! "$dimension" =~ ^[0123456789]+x[0123456789]+$ ]]; then
printf '%s %s\n' "'$dimension'" 'is not a valid dimension.'
fi
regex
sollte mit verankert werden^...$
, andernfallsfoo1x1fubar
würde es als gültige Dimension betrachtet werden.
Denken Sie auch daran, keine Bereiche wie für die Eingabevalidierung zu verwenden 0-9
, insbesondere wenn es um die Bereinigung in sicherheitsrelevanten Kontexten geht, da diese Bereiche in vielen Gebietsschemas viel mehr Zeichen enthalten (oder möglicherweise aus mehreren Zeichen bestehende Sortierelemente) als früher (und im Gebietsschema C/POSIX immer noch tun).
Für hilft 's =~
hier nicht. Unter Ubuntu 19.10 und in der Locale finde ich, dass 's zusätzlich zu 0123456789 mit oder ohne 1040 verschiedenen Zeichen übereinstimmt . Zumindest in meinem Fall haben sie alle eine Beziehung zu den Dezimalziffern 0 bis 8, aber das ist nicht einmal allgemein garantiert.bash
globasciiranges
en_GB.UTF-8
bash
[0-9]
globasciiranges
Andererseits stimmt [[:digit:]]
und [0123456789]
nur mit diesen 10 überein und sollte auf jedem POSIX-kompatiblen System übereinstimmen.
sh
Sie können dies auch mithilfe der Standardsyntax und Platzhaltermustern tun, etwa mit:
valid_geometry() case $1 in
(*[!x0123456789]* | *x | x* | *x*x*) false;;
(*x*) true;;
(*) false;;
esac
if ! valid_geometry "$dimension"; then
...
fi
Oder mit KSH-Globs (wie auch von bash -O extglob
und bash
sogar [[
ohne unterstützt extglob
) mit:
if [[ $dimension != +([0123456789])x+([0123456789]) ]]; then
...
fi
Antwort2
Okay, das scheint zu funktionieren:
if [[ ! "$dimension" =~ [0-9]+x[0-9]+ ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
aber ich frage mich, warum das Einschließen in einfache Anführungszeichen nicht funktioniert:
if [[ ! "$dimension" =~ '[0-9]+x[0-9]+' ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
hier ist meine Lösung:
dimension="3x5"
regex='[0-9]+x[0-9]+'
if [[ ! "$dimension" =~ $regex ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
Jetzt können Sie einfache Anführungszeichen verwenden, um den regulären Ausdruck zu zitieren, aber Sie müssen die doppelten Anführungszeichen vermeiden, wenn Sie innerhalb von [[ ]] auf $regex verweisen. Ich bin jedoch immer noch neugierig, ob es eine Abkürzung für [0-9]+
.. gibt.