You are not logged in.

#1 2009-11-15 07:03:16

Berticus
Member
Registered: 2008-06-11
Posts: 731

Why does this regular expression match (sh)?

I'm trying to have a yes/no prompt which accepts y, n, yes, no, and is case insensitive. I thought this would work:

until [[ "$yesno" =~ no?|y(es)? ]]
do
    read "Continue (yes/no)?" reply;
    yesno=`tr '[:upper:]' '[:lower:]' <<< "$reply"`;
    if [[ "$yesno" =~ no? ]]
    then
        exit 0;
    elif [[ "$yesno" =~ y(es)? ]]
    then
        # stuff to do
    else
        "Invalid input!";
done

The problem is ? seems to act more like a wildcard. I tested yn, and it matches. In fact as long as the first character is a Y, y, N, or n, it returns true. The only time ? acts the way it should (match preceding character once or none), is when another character follows it:

# 'non' and 'noun' will match
if [[ "$1" =~ nou?n ]]
then
    echo "$1 matches";
else
    echo "$1 does not match";
fi

I would like to know why it's working like this, and how do I fix it?

Offline

#2 2009-11-15 07:22:36

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: Why does this regular expression match (sh)?

i think you should use ^no?$ and ^y(es)?$


This silver ladybug at line 28...

Offline

#3 2009-11-15 08:20:58

Pox
Member
From: Melbourne, AU
Registered: 2007-10-04
Posts: 66

Re: Why does this regular expression match (sh)?

Yup, the issue is that you're only specifying y(es)? should appear somewhere in the string, not that it is the whole string - lolilolicon's suggestion should fix it.

Offline

#4 2009-11-15 09:41:35

RobertoVanto
Member
From: Chiampo(VI) - Italy
Registered: 2008-09-04
Posts: 32
Website

Re: Why does this regular expression match (sh)?

You could use the "case" conditional construct: http://www.gnu.org/software/bash/manual … Constructs


Love, and do what thou wilt  - St. Augustine of Hippo

Offline

#5 2009-11-16 17:12:48

nh
Member
From: England
Registered: 2008-07-09
Posts: 45

Re: Why does this regular expression match (sh)?

Instead of calling an external program, tr, you could let bash do the case conversion with parameter expansion:

yesno=${reply,,}

See 3.5.3 Shell Parameter Expansion.  This is more compact but more cryptic. Take your choice. wink

Or you could obviate the need for case conversion altogether by having bash do case-insensitive comparisons:

shopt -s nocasematch

But then, to prevent the nocasematch setting affecting the rest of the script, you'd have to save the old value of nocasematch and reset it when you've finished, or carry out the comparisons in a subshell (in which case any other variable settings done in the subshell will also be lost when the subshell ends), so I think it would be more hassle than it's worth.

Last edited by nh (2009-11-16 17:16:04)

Offline

Board footer

Powered by FluxBB