regex - procura caracter inválido

1

Usando

regex='^[]0-9a-zA-Z,!^'@{}=().;/~_|[-]*$'

no arquivo de script abaixo estou verificando se uma determinada string tem algum caracter inválido ou não.

str="$1"

regex='^[]0-9a-zA-Z,!^'@{}=().;/~_|[-]+$'

if [[ $str =~ $regex ]]
then
  echo "matches"
  echo "Match: ${BASH_REMATCH[0]}"
else
  echo "doesn't match"
fi

Como há uma opção para obter uma string combinada usando BASH_REMATCH, existe alguma opção para obter qual caractere inválido estava presente na string se a string não corresponder?

    
por Batty 24.11.2015 / 18:19

4 respostas

3

Eu não vi uma opção interna, então aqui está uma ideia:

#!/bin/bash

str="$1"

regex='^[]0-9a-zA-Z,!^'@{}=().;/~_|[-]+$'

if [[ $str =~ $regex ]]
then
  echo "matches"
  echo "Match: ${BASH_REMATCH[0]}"
else
  echo "doesn't match"
  for (( i = 0; i < ${#str}; i++ )) do
    c=${str:$i:1}
    if [[ ! $c =~ $regex ]]
    then
      echo Non-matching character at index $i: "$c"
    fi
  done
fi

Ele simplesmente percorre o caractere $str por caractere, comparando esse caractere com o $regex .

    
por 24.11.2015 / 18:38
2

Você pode negar sua expressão regular para encontrar o primeiro caractere inválido

Sua regex atual

$ str="in below script file I am checking if a given string has any invalid characters or not."
$ regex='^[]0-9a-zA-Z,!^'@{}=().;/~_|[-]+$'
$ [[ $str =~ $regex ]] && echo pass || echo fail
fail

Falha nos espaços. Negar o regex: remova as âncoras de linha e o quantificador + final; nega a expressão de colchetes - temos o conjunto de não caracteres válidos:

regex='[^]0-9a-zA-Z,!^'@{}=().;/~_|[-]'

Então

$ [[ $str =~ $regex ]] && echo "fail: found '${BASH_REMATCH[0]}'"
fail: found ' '
    
por 24.11.2015 / 19:30
1
cls='],_[:alnum:]!^'@{}=().;/~|[-'

while getopts : na "-$str"
do    case $OPTARG   in ([!$cls])
           printf %s\n "$OPTARG"
      esac
done

O analisador de opções getopts do shell funciona removendo iterativamente um caractere de string por caractere e atribuindo seu caractere de strip mais recente a uma variável de shell. Então, se você quiser separar uma string, getopts pode torná-la bastante conveniente. Tudo o que você precisa fazer depois é testar o caractere da iteração atual para validade . Se corresponder, deixe-o em paz, mas, se ! não, printf it.

    
por 29.12.2015 / 17:16
0

Isso vai pegar os caracteres que correspondem:

regex=']0-9a-zA-Z,!^'@{}=().;/~_|[-'

echo "$str" | grep -oP '^['"$regex"']*'

Capturando em um var e removendo do começo da string original:

head="$(echo "$str" | grep -oP '^['"$regex"']*')"

tail="${str#"$head"}"

Por fim, receba o primeiro caractere que falhou:

failedChar="${tail:0:1}"          # higher shells method.
failedChar="${tail"${tail#?}"}"    # Alternative method.

Usando BASH_REMATCH

str="Testing that this is working."
regex=']0-9a-zA-Z,!^'@{}=().;/~_|[-'
[[ $str =~ ^[$regex]* ]]

head="${BASH_REMATCH[0]}"

tail="${str#"$head"}"

failedChar="${tail%"${tail#?}"}"

echo "fc |$failedChar| at position ${#head}"
    
por 25.11.2015 / 22:48