Я пытаюсь сделать что-то достаточно общее: ввод данных пользователем Синтаксического анализа в сценарии оболочки. Если пользователь обеспечил допустимое целое число, сценарий делает одну вещь, и если не допустимый, это делает что-то еще. Проблема, я не нашел легкое (и довольно изящный) способом сделать это - я не хочу должным быть выбирать его независимо символ символом.
Я знаю, что это должно быть легко, но я не знаю как. Я мог сделать это на дюжине языков, но не Bash!
В моем исследовании я нашел это:
И существует ответ там, который говорит о regex, но насколько я знаю, это - функция, доступная в C (среди других). Однако, это имело то, что было похоже на большой ответ, таким образом, я попробовал его grep, но grep не знал, что сделать с ним. Я попробовал-P, который на моем поле означает рассматривать его как Perl regexp - nada. Тире E (-E) не работал также. И ни один не сделал-F.
Только, чтобы быть ясным, я пробую что-то вроде этого, ища любой вывод - оттуда, я изрублю сценарий для использования в своих интересах независимо от того, что я добираюсь. (IOW, я ожидал, что несоответствующий вход ничего не возвращает, в то время как допустимая строка повторяется.)
snafu=$(echo "$2" | grep -E "/^[-+]?(?:\.[0-9]+|(?:0|[1-9][0-9]*)(?:\.[0-9]*)?)$/")
if [ -z "$snafu" ] ;
then
echo "Not an integer - nothing back from the grep"
else
echo "Integer."
fi
Кто-то проиллюстрировал бы, как это наиболее легко сделано?
Откровенно говоря, это - недостаток ТЕСТА, по-моему. Это должно иметь флаг как это
if [ -I "string" ] ;
then
echo "String is a valid integer."
else
echo "String is not a valid integer."
fi
[[ $var =~ ^-?[0-9]+$ ]]
^
указывает начало входного шаблона -
является буквальным "-" ?
означает «0 или 1 из предшествующих ( -
]» +
означает «1 или более из предыдущих ( [0-9]
) " $
указывает конец входного шаблона Таким образом, регулярное выражение соответствует необязательному -
(для случая отрицательных чисел), за которым следует одна или несколько десятичных цифр.
Ссылки :
Можно взглянуть на реализацию Model-View-View Model в WPF .
Это не рамка, как .NET MVC, но в ее основе MVC является образцом, а MVVM является близким аналогом для WPF.
-121--4407445- Поэтому был создан const _ cast
. Просто помните, чтобы не стрелять ногой.
Изменить: ОК, я признаю - const_cast не был сделан для этой проблемы вообще. Это может сработать с вашим компилятором, но вы не можете рассчитывать на это, и если демоны вылетят из ваших ноздрей, пожалуйста, не вините меня.
-121--3842614- Для обеспечения переносимости до-Bash 3,1 (когда был введен тест = ~
) используйте expr
.
if expr "$string" : '-\?[0-9]\+$' >/dev/null
then
echo "String is a valid integer."
else
echo "String is not a valid integer."
fi
expr STRING: REGEX
выполняет поиск REGEX, привязанного в начале ПОСЛЕДОВАТЕЛЬНОСТЬ, повторяя первую группу (или длину совпадения, если нет) и возвращая успех/сбой. Это старый синтаксис regex, следовательно, избыток \
. -\?
означает «может быть -
», [0-9 ]\+
означает «одну или несколько цифр», а $
означает «конец последовательности».
Bash также поддерживает расширенные глобусы, хотя я не помню, с какой версии.
shopt -s extglob
case "$string" of
@(-|)[0-9]*([0-9]))
echo "String is a valid integer." ;;
*)
echo "String is not a valid integer." ;;
esac
# equivalently, [[ $string = @(-|)[0-9]*([0-9])) ]]
@ (- |)
означает « -
или ничего», [0-9]
означает «цифра», а * ([0-9])
означает «ноль или больше цифр».
Вы можете удалить нецифровые данные и провести сравнение. Вот демо-скрипт:
for num in "44" "-44" "44-" "4-4" "a4" "4a" ".4" "4.4" "-4.4" "09"
do
match=${num//[^[:digit:]]} # strip non-digits
match=${match#0*} # strip leading zeros
echo -en "$num\t$match\t"
case $num in
$match|-$match) echo "Integer";;
*) echo "Not integer";;
esac
done
Вот как выглядит результат теста:
44 44 Integer -44 44 Integer 44- 44 Not integer 4-4 44 Not integer a4 4 Not integer 4a 4 Not integer .4 4 Not integer 4.4 44 Not integer -4.4 44 Not integer 09 9 Not integer
Вот еще один вариант (только с использованием встроенной команды test и ее кода возврата):
function is_int() { return $(test "$@" -eq "$@" > /dev/null 2>&1); }
input="-123"
if $(is_int "${input}");
then
echo "Input: ${input}"
echo "Integer: $[${input}]"
else
echo "Not an integer: ${input}"
fi
Мне нравится решение, использующее тест -eq
, потому что оно в основном однострочное.
Мое собственное решение заключалось в том, чтобы использовать расширение параметра, чтобы отбросить все числа и посмотреть, осталось ли что-нибудь. (Я все еще использую 3.0, раньше не использовал [[
или expr
, но рад их видеть.)
if [ "${INPUT_STRING//[0-9]}" = "" ]; then
# yes, natural number
else
# no, has non-numeral chars
fi