Regex to allow spaces in string - bash - regex

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 :)

Related

Check if 2 substrings are present in string bash

I want to check if the letters "d" and "y" are present in string str at the same time in any order.
If I try OR operator | within the regex (d|y) evaluates to true if "d" or "y" are in string, but if use the AND operador & doesn´t work and evaluates to false even
both letters exist in string.
What would be the correct way to check this?
This is what I tested so far
str="good day"
if [[ $str =~ (d|y) ]] # This works for OR operator
if [[ $str =~ (d&y) ]] # doesn´t work for AND operator
then
echo "yes"
else
echo "no"
fi
Thanks in advance.
if [[ $str =~ (d.*y)|(y.*d) ]]; then
or if you don't want to repeat the d and y:
if [[ $str =~ d ]] && [[ $str =~ y ]] ; then

Bash regex comparison issue

I have the following function
checkFormat()
{
local funcUserName=$1
if [[ "$funcUserName" != [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9] ]];then
echo "1"
else
echo "0"
fi
}
if [[ $string != [a-zA-Z0-9]* ]]
Only returns true if the first character is not [a-zA-Z0-9]
if [[ $string != [a-zA-Z0-9]{5} ]]
Never returns true.
if [[ $string != [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9] ]]
Returns as I want it to.
Why is this?
The code is to check that a username is 5 characters long and alphanumeric i.e.
Joe12 or 12345 but not %$134.
bash version 4.2.37
I suggest to replace
if [[ $string != [a-zA-Z0-9]{5} ]]
by
if [[ ! $string =~ ^[a-zA-Z0-9]{5}*$ ]]
to match a regex.

Why does this regexp matches to almost everything?

I cant really explain but check out the following:
name=$1
pat="\b[0-9a-zA-Z_]+\b"
if [[ $name =~ $pat ]]; then
echo "$name is ok as user name"
else
echo "$name is not ok as user name"
exit 1
fi
Test run:
./script test_user+
test_user+ is ok as user name
The username with a + sign should not match that regexp.
First of all:
\b is a PCRE extension; it isn't available in ERE, which the =~
operator in bash's [[ ]] syntax uses.
(From Bash regex match with word boundary)
Second, you don't want word boundaries (\b) if you wish to force the entire string to match. You want to match the start (^) and end ($):
pat="^[0-9a-zA-Z_]+\$"
if you dont want word bondry (guessed as you are trying username match) please use
^[0-9a-zA-Z_]+$
Contrary to the OP's experience and other answer it seems \b is supported on Ubuntu 14.04, bash 4.3.11 as word boundary. Here is a sample:
re='\bb[0-9]+\b'
[[ 'b123' =~ $re ]] && echo "matched" || echo "nope"
matched
[[ 'b123_' =~ $re ]] && echo "matched" || echo "nope"
nope
Even \< and \> also work fine as word boundaries:
re='\<b[0-9]+\>'
[[ 'b123' =~ $re ]] && echo "matched" || echo "nope"
matched
[[ 'b123_' =~ $re ]] && echo "matched" || echo "nope"
nope
However support of \b is specific to certain OS only. e.g. on OSX following works as word boundary:
[[ 'b123' =~ [[:\<:]]b[0-9]+[[:\>:]] ]] && echo "matched" || echo "nope"
matched
[[ 'b123_' =~ [[:\<:]]b[0-9]+[[:\>:]] ]] && echo "matched" || echo "nope"
nope

regex with variable length

In Bash, can we match varying length of strings?
Eg.,
regex="FOO[0-9]{5}"
if [[ $1 =~ ${regex} ]]
will match FOO1111 or FOO98765 right...
But how do we match FOO1, FOO123 and FOO12345?
regex="FOO[0-9]{1-5}" doesnt work.
Is there a way do that in a simple manner or we just use:
regex5="FOO[0-9]{5}"
regex4="FOO[0-9]{4}"
regex3="FOO[0-9]{3}"
regex2="FOO[0-9]{2}"
regex="FOO[0-9]"
if [[ $1 =~ ${regex} || $1 =~ ${regex2} || $1 =~ ${regex3} || $1 =~ ${regex4} || $1 =~ ${regex5} ]]
You can use {min,max}:
regex="FOO[0-9]{1,5}"
And in fact you can use ^ and $ for exact match:
[[ $v =~ ^${regex}$ ]]
Test
$ v=FOO
$ [[ $v =~ ^${regex}$ ]] && echo "yes"
$
$ v=FOO1
$ [[ $v =~ ^${regex}$ ]] && echo "yes"
yes
$ v=FOO123456
$ [[ $v =~ ^${regex}$ ]] && echo "yes"
$

Regex match a string with spaces (use quotes?) in an if statement

How would I do a regex match as shown below but with quotes around the ("^This") as in the real world "This" will be a string that can have spaces in it.
#!/bin/bash
text="This is just a test string"
if [[ "$text" =~ ^This ]]; then
echo "matched"
else
echo "not matched"
fi
I want to do something like
if [[ "$text" =~ "^This is" ]]; then
but this doesn't match.
You can use \ before spaces.
#!/bin/bash
text="This is just a test string"
if [[ "$text" =~ ^This\ is\ just ]]; then
echo "matched"
else
echo "not matched"
fi
I did not manage to inline the expression like this:
if [[ "$text" =~ "^ *This " ]]; then
but if you put the expression in a variable you could use normal regex syntax like this:
pat="^ *This "
if [[ $text =~ $pat ]]; then
Note that the quoting on $text and $pat is unnessesary.
Edit:
A convinient oneliner during the development:
pat="^ *This is "; [[ " This is just a test string" =~ $pat ]]; echo $?
can you make your problem description clearer?
text="This is just a test string"
case "$text" in
"This is"*) echo "match";;
esac
the above assume you want to match "This is" at exactly start of line.
Have you tried:
^[\s]*This