Correspondência de padrões de shell e operadores aritméticos (+ - * /%)

0

Isso parece tão simples, mas não é:

[[ "1234+5678" =~ [0-9]+(\s*(\-|\*)\s*[0-9]+)* ]] && echo $?

retorna um 0 . No entanto, na verdade, isso não deve ser feito, pois apenas o operador menos ( - ) e multiplicação ( * ) são permitidos. Além disso, peguei algumas ferramentas de regex na rede e tentei corresponder a esse padrão: result foi a string nula. (como esperado)

Na prosa, esta regex estendida diz:

  • procure por número (obrigatório)
  • verifique se há algum espaço em branco
  • O operador
  • deve ser um - ou um *
  • verifique se há algum espaço em branco (novamente)
  • procure outro número (deve estar lá se precedido por um operador)

Além disso, o asterisco após a expressão entre parênteses diz que o segundo ao enésimo par de números do operador é opcional.

Onde está o meu erro em pensar aqui?

    
por syntaxerror 23.06.2015 / 22:32

3 respostas

3

Sem marcadores, o regexp (parte direita) pode corresponder a qualquer parte da string. Então, sua variante corresponde a 1234 . Para satisfazer os requisitos, você precisa usar marcadores:

[[ "1234+5678" =~ ^[0-9]+(\s*(\-|\*)\s*[0-9]+)*$ ]] ; echo $?

E mais curto (se você quiser):

[[ "1234+5678" =~ ^[0-9\ *-]+*$ ]] ; echo $?
    
por 23.06.2015 / 23:06
1

Sua expressão retorna 0 porque corresponde ao primeiro número. Ancore o regexp para fazer o que você deseja:

[[ "1234+5678" =~ ^[0-9]+( *(-|\*) *[0-9]+)*$ ]] && echo $?

Em uma nota lateral: (1) você não precisa citar - e (2) \s não é reconhecido como ERE.

    
por 23.06.2015 / 23:12
0
[[ "1234+5678" =~ [0-9]+(\s*(\-|\*)\s*[0-9]+) ]] ; echo $?

O operador * regex no final do seu regex permite qualquer número de repetições da expressão dentro do () e também nenhum. Então você combina [0-9] + desde o início e o resto é opcional.

Se você remover o * ou substituí-lo por um + , a expressão retornará como esperado.

Also, the asterisk following the expression in parentheses says that 2nd to nth operator-number pair is optional.

Esse é o erro: O * significa que qualquer operador é uma opção. Use o operador + !

Ok, essa não foi a resposta, mas você pode consumir as expressões e ver se o resultado está vazio:

echo "1234*5678"|sed 's/[0-9]\+\([ \*\-][0-9]\+\)*//'
    
por 23.06.2015 / 22:41