Esto es sintácticamente incorrecto:
#!/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
lo anterior tiene una sintaxis incorrecta... entonces mi pregunta es: ¿hay alguna manera de hacerlo?!=~
...Supongo que es !~
? Si eso es cierto, hasta aquí las reglas de negación lulz. Muy bien, lo probé y !~
tampoco funciona.
Respuesta1
No hay operadores !=~
u !~
para la [[
palabra clave. En lugar de ello, niega el resultado de la comparación:
[[ ! "string" =~ regex ]]
Respecto a citar el regex
argumento, el manual dice:
Se puede citar cualquier parte del patrón para forzar que la parte citada coincida como una cadena.
Por lo tanto, las partes de expresiones regulares de regex
no deben citarse, a menos que compat31
esté configurada la opción de shell:
shopt
...compat31
Si se establece, bash cambia su comportamiento al de la versión 3.1 con respecto a los argumentos citados para el operador
[[
del comando condicional.=~
Para el ejemplo dado, intente:
if [[ ! "$dimension" =~ ^[0123456789]+x[0123456789]+$ ]]; then
printf '%s %s\n' "'$dimension'" 'is not a valid dimension.'
fi
regex
debe estar anclado con^...$
, de lo contrariofoo1x1fubar
se considerará una dimensión válida.
También recuerde no usar rangos como 0-9
para la validación de entradas, especialmente si es para desinfección en contextos sensibles a la seguridad, ya que en muchas configuraciones regionales, estos rangos incluyen muchos más caracteres (o posiblemente elementos de recopilación compuestos por varios caracteres) que históricamente (y todavía lo hago en la configuración regional C/POSIX).
Porque =~
' bash
s globasciiranges
no ayuda aquí. En Ubuntu 19.10 y en la en_GB.UTF-8
configuración regional, encuentro bash
coincidencias [0-9]
en 1040 caracteres diferentes además de 0123456789, con o sin globasciiranges
. Al menos en mi caso, todos tienen alguna relación con los dígitos decimales del 0 al 8, pero eso ni siquiera está garantizado en general.
Por otro lado, [[:digit:]]
y [0123456789]
coincide solo con esos 10 y debería hacerlo en cualquier sistema compatible con POSIX.
También puedes hacerlo usando sh
sintaxis estándar y patrones comodín con algo como:
valid_geometry() case $1 in
(*[!x0123456789]* | *x | x* | *x*x*) false;;
(*x*) true;;
(*) false;;
esac
if ! valid_geometry "$dimension"; then
...
fi
O con ksh globs (como también lo admite bash -O extglob
and bash
's [[
even without extglob
) con:
if [[ $dimension != +([0123456789])x+([0123456789]) ]]; then
...
fi
Respuesta2
Muy bien, esto parece funcionar:
if [[ ! "$dimension" =~ [0-9]+x[0-9]+ ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
pero me pregunto por qué envolverlo entre comillas simples no funciona:
if [[ ! "$dimension" =~ '[0-9]+x[0-9]+' ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
aquí está mi solución:
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
Ahora puede utilizar comillas simples para citar la expresión regular, pero debe evitar las comillas dobles cuando haga referencia a $regex desde [[ ]]. Sin embargo, todavía tengo curiosidad por saber si hay una abreviatura para [0-9]+
...