0

Below, I use ALLOWED as container to test a token. I am using a Bash regex match syntax =~ where the right hand side should be an extended regular expression.

In Bash's Regular Expression Matching. Using the operator =~, the left hand side operand is matched against the extended regular expression (ERE) on the right hand side. Check a related question on using date regex.

But I can't see str1 as a regex and I don't know why ALLOWED matches a string which is present inside it. Even as this works in this case, having regex (str1) as the test string leaves it open for tricky bugs in future.

export ALLOWED="str0 str1 strn"
export STR1="str1"
export STR2="str2"

if [[ $ALLOWED =~ ${STR1} ]]; then
    echo "how does it this work?"
fi

if [[ $ALLOWED =~ ${STR2} ]]; then
    :
else
    echo "does not work."
fi

Questions:

  • Why/ How does this work?
  • What's a better to do test for an element in a list in bash?
Community
  • 1
  • 1
Senthil Kumaran
  • 54,681
  • 14
  • 94
  • 131
  • 3
    I dont' quite understand - what do you observe that you didn't expect? The first regex matches, and the second doesn't, right? – Benjamin W. Mar 14 '16 at 22:27
  • You example works exactly as expected, what are you trying to do here? The question you ask *What's a better to do test for an element in a list in bash?*, is a different one, bash has a list/array data structure, you can store something in that and then test for membership, using a string for this is a terrible hack. – ffledgling Mar 14 '16 at 22:33
  • I mentioned " I am using a Bash regex match syntax =~ where the right hand side should be an extended regular expression", How is str1 and str2 a regex syntax for ALLOWED? – Senthil Kumaran Mar 14 '16 at 22:49
  • 1
    `str1` is the literal string `str1` when interpreted as a regex, and that string is contained in `ALLOWED`, so it matches. `str2` is not contained in `ALLOWED`, so it doesn't match. – Benjamin W. Mar 14 '16 at 23:06
  • It can be wrong if `export STR1="str"` still pass `[[ $ALLOWED =~ ${STR1} ]]; ` – Tim007 Mar 14 '16 at 23:11

2 Answers2

0

The syntax is content =~ regex, for example think about how this simple phone number validation works

$ phone="555-443-2321"; if [[ $phone =~ [0-9-]+ ]]; then echo PASS; fi 

as in your example, the right hand side is the regular expression and left hand side is the content.

Your regex can be a string literal, then the check will be whether content contains that substring

$ phone="555-443-2321"; if [[ $phone =~ "555" ]]; then echo PASS; fi

if it makes it easier for you think that as a regex for .*555.*

karakfa
  • 66,216
  • 7
  • 41
  • 56
0

If I understand right, the confusion is because $a =~ $b checks whether there's a match for $b in $a, not whether $a as a whole matches. [[ "str0 str1 strn" =~ str1 ]] succeeds because there's a match for the (trivial) regex str1 somewhere in "str0 str1 strn".

If you want to check for a match to the entire string, you need to anchor the regex with a ^ at the beginning, and $ at the end: [[ $ALLOWED =~ ^${STR1}$ ]]

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151