2017-02-01 4 views
0

регулярного выражения я работаю на данный момент выглядит следующим образом:Regex «начало строки» якорь не работают

^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$ 

Я пытаюсь соответствовать всем числам с плавающей точкой, но только число. Например, следующее должно соответствовать:

  • 6,0
  • 1.22E3
  • -2
  • 2.99999e-12

Однако следующий не должны совпадать:

  • somestring /////// 6.0

Я проверил указанное выше регулярное выражение на this validation site, и он работает так, как ожидалось. Однако при запуске в моем сценарии bash ничего не происходит.

Это мой Баш код:

if [[ "$VAL" =~ ^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$ ]] 
    then 
     echo $VAL, "is a number" 
    else 
     echo $VAL, "is not a number" 
fi 

Я попытался удалить якоря, и он соответствует любым строкам, которые содержат плавающую точку. Однако строки, такие как «//////6.00007», совпадают. $ Anchor работает, как ожидалось; однако,^не.

Пожалуйста, дайте мне знать, если у вас есть предложения по устранению этой проблемы.

Спасибо!

Редактировать 1

Удален плохие примеры

Edit 2

Я побежал регулярное выражение в своем собственном foo.sh как предложено @lurker и код побежал, как ожидается, с моими тестовыми случаями , Поэтому я посмотрел, что сравнивалось с регулярным выражением. Когда я оценивал, что сравнивалось, все выглядело отлично, поэтому он не обращал внимания на то, почему регулярное выражение не совпало.

Тогда я начал подозревать, что echo не показывало, что было на самом деле в $VAL по какой-то причине.

Итак, я использовал это: NEWVAL=(echo $VAL) как временное обходное решение, пока не смогу выяснить, что происходит.

+2

Я пробовал ваше регулярное выражение и скрипт как есть, и они, похоже, работают отлично для меня. '" //////6.00007 "вышел" не число ". – lurker

+0

Странно. Каковы возможности? Зачем вы запускаете скрипт, а не меня? – kgrimes2

+3

Как вы запускали свой скрипт? Покажите, что именно вы сделали. Я помещаю ваш код в файл 'foo.sh', затем' export VAL = "6" 'и запускал' bash foo.sh', и он сказал: '6, является числом'. Затем я выполнил 'export VAL =" /////// 6.000007 "и запустил' bash foo.sh', и он сказал: '///////6.000007, не является числом'. Вы можете сделать 'bash --version' и сообщить, какую версию' bash' вы используете. – lurker

ответ

0

Как выясняется, переменные, которые я сравнивал с моим регулярным выражением был ведущим новой строки на них (например, "\n2.3333"), которые были убраны с echo. Итак, когда я отобразил значения на экране с echo, я увидел бы разделенную версию моей переменной, которая не была сопоставлена ​​с регулярным выражением.

Услышано: echo не всегда заслуживает доверия. За @ комментарий CharlesDuffy, используйте одно из следующих действий, чтобы увидеть, что на самом деле в ваших переменных: declare -p varname или printf '%q\n' "$varname" но делать не использование echo $varname.

+0

Гораздо проще использовать 'echo '$ var" ' – wjandrea

1

Ваше регулярное выражение не допускает десятичных знаков в экспоненте. Экспоненты могут иметь десятичные значения, поэтому вам либо нужно изменить свое определение того, что такое «номер», либо вам нужно изменить ваше регулярное выражение.

Предполагая, что позже, вот исправление (Bash 4.4):

echo "6.0 
1.22E3.7 
-2 
2.99999e-0.0001 
somestring///////6.0" >/tmp/f1.txt 

while IFS= read -r line || [[ -n $line ]]; do 
    if [[ "$line" =~ ^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[-+]?[0-9]*\.?[0-9]+)?$ ]] 
     then 
      echo $line, "is a number" 
     else 
      echo $line, "is not a number" 
    fi 
done < /tmp/f1.txt 

Печать:

6.0, is a number 
1.22E3.7, is a number 
-2, is a number 
2.99999e-0.0001, is a number 
somestring///////6.0, is not a number 

НО вы должны знать, что большинство рассматривает только две цифры законным в вашем списке, чтобы быть 6.0 и -2. Легкий способ испытания с awk:

$ awk '$1+0==$1{print $0 " is a number"; next} {print $0 " not a number"}' /tmp/f1.txt 
6.0 is a number 
1.22E3.7 not a number 
-2 is a number 
2.99999e-0.0001 not a number 
somestring///////6.0 not a number 

Та же функция языка C, что awk использует для преобразования строки в число с плавающей точкой используется многими другими языками (Ruby, Perl, Python, C, C++, Swift, и т.д. и т. д.), поэтому, если вы считаете, что ваш формат действителен, вы, вероятно, тоже будете писать свою собственную процедуру конверсии.

Например, на большинстве языков вы можете ввести 10**1.5 как законный плавающий литерал. Ни один язык я знаю не принимает десятичных чисел после e в строку вида 'xx.zzEyy.y'

+0

Прошу прощения, те «числа», которые у меня были в моем посте, были плохими примерами с головы и не были фактическими значениями, которые можно было бы сравнить с регулярным выражением. Как оказалось, по какой-то причине значения, хранящиеся в '$ VAL', отличались от того, что было напечатано на экране, когда я запускал на них« echo $ VAL ». Поэтому я сделал это: 'NEWVAR = $ (echo $ VAL)', и теперь он работает так, как ожидалось. Я понятия не имею, почему, но это так. – kgrimes2

+0

Я бы ожидал, что ваш '$ VAL' содержит ведущие пробелы. 'echo $ VAL' word-splits и glob - расширяет содержимое вашей переменной, а не печатает это содержимое как есть, поэтому он будет маскировать эту ошибку. –

Смежные вопросы