¿Qué hice mal aquí?
Intentando hacer coincidir cualquier cadena que contenga espacios, minúsculas, mayúsculas o números. Los personajes especiales también estarían bien, pero creo que eso requiere escapar de ciertos personajes.
TEST="THIS is a TEST title with some numbers 12345 and special char *&^%$#"
if [[ "$TEST" =~ [^a-zA-Z0-9\ ] ]]; then BLAH; fi
Obviamente, esto solo prueba para números superiores, inferiores, y espacios. Aunque no funciona.
* ACTUALIZAR *
Supongo que debería haber sido más específico. Aquí está la línea real de código real.
if [[ "$TITLE" =~ [^a-zA-Z0-9\ ] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; fi
* ACTUALIZAR *
./anm.sh: line 265: syntax error in conditional expression
./anm.sh: line 265: syntax error near `&*#]'
./anm.sh: line 265: ` if [[ ! "$TITLE" =~ [a-zA-Z0-9 $%^\&*#] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; return; fi'
regex
bash
if-statement
Atomiklan
fuente
fuente
re='...whatever...'; [[ $string =~ $re ]]
(sin comillas, este es uno de los raros casos en los que romperán algo que funcionaría sin ellas).[[ $var =~ .* ]]
para coincidir con expresiones regulares.*
(cualquier cosa). Supongo que si usa comillas, las citas en sí mismas se consideran parte de la expresión regular…pattern='^hello[0-9]*$'
(2.) en la expresión de doble cuadrado si necesita coincidencia de expresiones regulares NO cite el patrón porque las citas DESACTIVAN la coincidencia de patrones de expresiones regulares. (es decir, la expresión[[ "$x" =~ $pattern ]]
coincidirá con el uso de expresiones regulares y la expresión[[ "$x" =~ "$pattern" ]]
deshabilita la coincidencia de expresiones regulares y es equivalente a[[ "$x" == "$pattern" ]]
).Respuestas:
Hay un par de cosas importantes que debes saber sobre la
[[ ]]
construcción de bash . El primero:La segunda cosa:
En consecuencia,
$v
en cualquier lado de=~
se expandirá al valor de esa variable, pero el resultado no será dividido por palabras ni expandido por nombre de ruta. En otras palabras, es perfectamente seguro dejar las expansiones variables sin comillas en el lado izquierdo, pero debe saber que las expansiones variables ocurrirán en el lado derecho.Entonces, si escribe:,
[[ $x =~ [$0-9a-zA-Z] ]]
el$0
interior de la expresión regular a la derecha se expandirá antes de que se interprete la expresión regular, lo que probablemente hará que la expresión regular no se compile (a menos que la expansión de$0
extremos con un dígito o símbolo de puntuación cuyo valor ascii sea menor que un dígito). Si cita el lado derecho así[[ $x =~ "[$0-9a-zA-Z]" ]]
, entonces el lado derecho se tratará como una cadena ordinaria, no como una expresión regular. (y$0
aún se expandirá). Lo que realmente quieres en este caso es[[ $x =~ [\$0-9a-zA-Z] ]]
De manera similar, la expresión entre
[[
y]]
se divide en palabras antes de que se interprete la expresión regular. Por lo tanto, los espacios en la expresión regular deben escaparse o citarse. Si quería hacer coincidir letras, dígitos o espacios que podría utilizar:[[ $x =~ [0-9a-zA-Z\ ] ]]
. De manera similar, otros caracteres deben tener un escape, como#
, que iniciaría un comentario si no se cita. Por supuesto, puede poner el patrón en una variable:pat="[0-9a-zA-Z ]" if [[ $x =~ $pat ]]; then ...
Para las expresiones regulares que contienen muchos caracteres que necesitarían ser escapados o entre comillas para pasar por el lexer de bash, mucha gente prefiere este estilo. Pero cuidado: en este caso, no puede citar la expansión de la variable:
# This doesn't work: if [[ $x =~ "$pat" ]]; then ...
Finalmente, creo que lo que está tratando de hacer es verificar que la variable solo contiene caracteres válidos. La forma más sencilla de realizar esta comprobación es asegurarse de que no contiene un carácter no válido. En otras palabras, una expresión como esta:
valid='0-9a-zA-Z $%&#' # add almost whatever else you want to allow to the list if [[ ! $x =~ [^$valid] ]]; then ...
!
niega la prueba, convirtiéndola en un operador "no coincide", y un[^...]
clase de carácter regex significa "cualquier carácter que no sea...
".La combinación de la expansión de parámetros y los operadores de expresiones regulares puede hacer que la sintaxis de la expresión regular de bash sea "casi legible", pero todavía existen algunos errores. (¿No son siempre?) Una de ellas es que no se podía poner
]
en$valid
, incluso si$valid
fueron citados, excepto en el principio. (Esa es una regla de expresiones regulares de Posix: si desea incluir]
en una clase de carácter, debe ir al principio.-
Puede ir al principio o al final, por lo que si necesita ambos]
y-
, debe comenzar con]
y terminar con-
, que conduce a la expresión regular "yo sé lo que estoy haciendo" emoticon:[][-]
)fuente
if ! [[ $x =~ $y ]]
oif [[ ! $x =~ $y ]]
SC2076: Don't quote rhs of =~, it'll match literally rather than as a regex.
[[
y]]
" se analizan del texto del programa, de la misma manera que las líneas de comando se analizan en palabras. Sin embargo, a diferencia de las líneas de comando, las palabras no se dividen después de las expansiones.En caso de que alguien quisiera un ejemplo usando variables ...
#!/bin/bash # Only continue for 'develop' or 'release/*' branches BRANCH_REGEX="^(develop$|release//*)" if [[ $BRANCH =~ $BRANCH_REGEX ]]; then echo "BRANCH '$BRANCH' matches BRANCH_REGEX '$BRANCH_REGEX'" else echo "BRANCH '$BRANCH' DOES NOT MATCH BRANCH_REGEX '$BRANCH_REGEX'" fi
fuente
Preferiría usar
[:punct:]
para eso. Además,a-zA-Z09-9
podría ser solo[:alnum:]
:[[ $TEST =~ ^[[:alnum:][:blank:][:punct:]]+$ ]]
fuente