How to match regular expressions with an if statement - regex

I am trying to perform a simple comparison within an if statement
basically it is taking the input from a user and then checking to verify that it is a proper entry.
This specific script is checking serial numbers.
read -p "enter in you serial number: serial_number
if [[ $serial_number == FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
then echo -e "validation passed"
else echo -e "validation failed"
fi
However if I enter FOO123-ABCD, I get validation failed.
The only way I have been able to get it to work is much uglier
if $serial_number == [A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]-[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9] ]]
Is there something I am doing wrong with the curly braces or is there some switch I have to use in order to compare extended expressions?
So far I have tried:
[[ "$serial_number" == FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "$serial_number" == "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]
[[ "${serial_number}" == FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "${serial_number}" == "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]
[[ "$serial_number" =~ FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "$serial_number" =~ "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]
[[ "${serial_number}" =~ FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "${serial_number}" =~ "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]

This is working fine for me:
read -p "enter in you serial number:" serial_number
echo ">>$serial_number<<"
if [[ "$serial_number" =~ ^FOO[A-Z0-9]{3}-[A-Z0-9]{4}$ ]]; then
echo -e "validation passed"
else
echo -e "validation failed"
fi
Note you need the ^ and $. Else it's checking for an occurrence anywhere in the string (like egrep).

Related

Regex to allow spaces in string - bash

I can't get a string with spaces to validate. It works without spaces, but when I include a space in the string it fails. I have googled furiously but can't get it to work.
if [[ $string =~ ^"[A-Za-z ]"$ ]]; then
# true
else
# false
fi
I'm not sure what I'm missing here...
Use a variable to store your regex:
re='^[A-Za-z ]+$'
Then use it as:
[[ "string" =~ $re ]] && echo "matched" || echo "nope"
matched
[[ "string with spaces" =~ $re ]] && echo "matched" || echo "nope"
matched
If you want inline regex then use:
[[ "string with spaces" =~ ^[A-Za-z\ ]+$ ]] && echo "matched" || echo "nope"
matched
Or else use [[:blank:]] property:
[[ "string with spaces" =~ ^[A-Za-z[:blank:]]+$ ]] && echo "matched" || echo "nope"
matched
I should instead use following regex if its always space instead..
if [[ $string =~ ^"[A-Za-z ](\s)"$ ]]; then
# true
else
# false
fi
Cheers :)

bash regex in 4.1

the following code works fine on 3.5 bash but not in 4.1
regex='^WORD\-([^(WORD2)][^[:space:]]{1,}$)|(WORD2[[:space:]][^[:space:]]{2,}$)'
if ! [[ $appname =~ $regex ]]
then
printf "no match"
ct_dev_error=$((ct_dev_error+1))
fi
any soliutions? or ideas?
Your regex can be simplified to this:
regex='^WORD-(WORD2[[:space:]][^[:space:]]{2,}|[^[:space:]]+)$'
Test it:
appname='WORD-APP' && [[ $appname =~ $regex ]] && echo "${BASH_REMATCH[0]}"
WORD-APP
appname='WORD-BUD APP' && [[ $appname =~ $regex ]] && echo "${BASH_REMATCH[0]}"
appname='WORD-WORD2 APP' && [[ $appname =~ $regex ]] && echo "${BASH_REMATCH[0]}"
WORD-WORD2 APP
[^(WORD2)] is not actually negating match of WORD2. It is actually a negated character class and it is basically matching a single character that is NOT one of the characters in this list (WORD2).

bash substring regex matching wildcard

I am doing bash , i try to test if the substring "world" in the given variable x. I have part of code working. But the other one not working. I want to figure out why
First one is working
x=helloworldfirsttime
world=world
if [[ "$x" == *$world* ]];then
echo matching helloworld
Second one is not working
x=helloworldfirsttime
if [[ "$x" == "*world*" ]];then
echo matching helloworld
How to make second one work without using variable like the 1st method
Can someone fix the second one for me.. thanks
Just remove the quotes:
x=helloworldfirsttime
if [[ "$x" == *world* ]]; then
echo matching helloworld
fi
Note that this isn't regex (a regex for this would look something like .*world.*). The pattern matching in bash is described here:
http://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html
x=helloworldfirsttime
$ if [[ "$x" == *world* ]]; then echo MATCHING; fi
MATCHING
This works because bash's builtin [[ operator treats the right-hand-side of an == test as a pattern:
When the == and != operators are used, the string to the right of the operator is used as a pattern and pattern matching is performed.
Next time if you want to provide patters with spaces you could just quote it around "" or '', only that you have to place the pattern characters outside:
[[ "$x" == *"hello world"* ]]
[[ "$x" == *'hello world'* ]]
[[ "$x" == *"$var_value_has_spaces"* ]]
You shold use without quotes and the =~ operator.
TEXT=helloworldfirsttime
SEARCH=world
if [[ "$TEXT" =~ .*${SEARCH}.* ]]; then echo MATCHING; else echo NOT MATCHING; fi
TEXT=hellowor_ldfirsttime
if [[ "$TEXT" =~ .*${SEARCH}.* ]]; then echo MATCHING; else echo NOT MATCHING; fi

Extended Regular Expression in UNIX

I don't mean that this question for UNIX only, but I work on Solaris, and I didn't try it on any other OS.
I confused between the extended regular expression:
first:
[[ "str" == ?(str|STR) ]] && echo "matched"
this work correct, but when:
[[ "str str" == ?(str|STR)(.*) ]] && echo "matched"
it doesn't work, does it mean that I can only compare one pattern.
Second:
[[ "str" =~ ?(str|STR) ]] && echo "matched"
I can't use this form here why?, but when:
[[ "str" == (str|STR)? ]] && echo "matched"
it works correctly.
It looks like you are trying to combine
extended globs
with
extended regular expressions. I would say this is A Bad Thing.
$ set '(str|STR)'
$ [[ 'str' =~ $1 ]] && echo matches
matches
$ [[ 'str str' =~ $1 ]] && echo matches
matches

Regular expression alteration not matching in BASH

I have been trying to get multiple not matching alteration to work in a BASH.
This is what I am trying to not match. If there are two parameters and a switch(-a,-b,-c,-d) is the first parameter.
Example:
./scriptname -a filename
./scriptname -d filename
What I want this to echo success is for:
./scriptname filename ipaddress.
The code that works is :
if [[ "$#" = "2" && "$1" =~ ([^-a][^-b][^-c]) ]]
then
echo "success"
else
echo "fail"
fi
If I try to expand on the alteration with ([^-a][^-b][^-c][^-d]) it stops working. I have tried multiple syntax variants and nothing seems to work. I also tried to group them together like:
if [[ "$#" = "2" && "$1" =~ ([^-a][^-b]) && "$1" =~ ([^-c][^-d]) ]] and this fails as well.
What about:
if [[ "$#" = "2" && "$1" =~ -[a-d]$ ]]