Reputation: 269
I have to match a string composed of only lowercase characters repeated 2 times , for example ballball
or printprint
. For example the word ball
is not accepted because is not repeated 2 time.
For this reason I have this code:
read input
expr='^(([a-z]*){2})$'
if [[ $input =~ $expr ]]; then
echo "OK string"
exit 0
fi
exit 10
but it doesn't work , for example if I insert ball
the script prints "OK string"
.
What do I wrong?
Upvotes: 1
Views: 79
Reputation: 52506
Not all Bash versions support backreferences in regexes natively. If yours doesn't, you can use an external tool such as grep
:
read input
re='^\([a-z]\+\)\1$'
if grep -q "$re" <<< "$input"; then
echo "OK string"
exit 0
fi
exit 1
grep -q
is silent and has a successful exit status if there was a match. Notice how (
, +
and )
have to be escaped for grep
. (grep -E
would understand ()
without escaping.)
Also, I've replaced your *
with +
so we don't match the empty string.
Alternatively: your requirement means that a matching string has two identical halves, so we can check for just that, without any regexes:
read input
half=$(( ${#input} / 2 ))
if (( half > 0 )) && [[ ${input:0:$half} = ${input:$half} ]]; then
echo "OK string"
fi
This uses Substring Expansion; the first check is to make sure that the empty string doesn't match.
Upvotes: 2
Reputation: 8456
The regex [a-z]* will match any alphanumeric or empty string.
([a-z]*){2}
will match any two of those.
Ergo, ^(([a-z]*){2})$
will match any string containing zero or more alphanumeric characters.
Using the suggestion from @hwnd (replacing {2}
with \1
) will enforce a match on two identical strings.
N.B: You will need a fairly recent version of bash. Tested in bash 4.3.11.
Upvotes: -1
Reputation: 5950
Your requirement is to match strings made of two repeated words. This is easy to do by just checking if the first half of your string is equal to the remaining part. No need to use regexps...
$ var="byebye" && len=$((${#var}/2))
$ test ${var:0:$len} = ${var:$len} && { echo ok ; } || echo no
ok
$ var="abcdef" && len=$((${#var}/2))
$ test ${var:0:$len} = ${var:$len} && { echo ok ; } || echo no
no
Upvotes: 0