Matching groups in bash regex [duplicate] - regex

This question already has answers here:
bash regex with quotes?
(5 answers)
Closed 5 years ago.
In bash I have the following:
REGEX="(1.0.0|2.0.0)"
declare -a arr=("A:1.0.0" "B:1.0.0" "C:2.0.0" "D:2.0.1")
for i in "${arr[#]}"
do
echo "Found: $i"
if [[ "$i"=~"${REGEX}" ]]; then
echo "$i matches: ${REGEX}"
else
echo "$i DOES NOT match: ${REGEX}"
fi
done
I would assume that for D:2.0.1 it would print ...DOES NOT match... but instead it prints
Found: A:1.0.0
A:1.0.0 matches: (1.0.0|2.0.0)
Found: B:1.0.0
B:1.0.0 matches: (1.0.0|2.0.0)
Found: C:2.0.0
C:2.0.0 matches: (1.0.0|2.0.0)
Found: D:2.0.1
D:2.0.1 matches: (1.0.0|2.0.0)
So what is wrong with my REGEX group pattern? Specifying a group pattern like that works fine in other languages - e.g. like groovy.

You have a a typo in the regex match expression to start with
if [[ "$i"=~"${REGEX}" ]]; then
should have been written as just
if [[ $i =~ ${REGEX} ]]; then
which implicates the point that you should never quote your regex expressions. For it to understand the | operator in its extended regular expressions support(ERE) you need to make it understand that it is not a literal string which it treats so when under double-quotes.
Not recommended
But if you still want to quote your regex strings - bash 3.2 introduced a compatibility option compat31 (under New Features in Bash 1.l) which reverts bash regular expression quoting behavior back to 3.1 which supported quoting of the regex string. You just need to enable it via an extended shell option
shopt -s compat31
and run it with quotes now
if [[ $i =~ "${REGEX}" ]]; then

Related

How can bash recognize regex groups? [duplicate]

This question already has answers here:
Capturing Groups From a Grep RegEx
(10 answers)
Closed 2 years ago.
I am trying to use regex to match a filename out of a path.
#!/bin/bash
regex=[^/]+?(?=.zip)
path="/home/quid/Downloads/file.zip"
if [[ $path =~ $regex ]]
then
echo "Found a match"
echo $BASH_REMATCH
fi
I should get
Found a match
file
Instead bash gives me this error
another.sh: line 2: syntax error near unexpected token `('
another.sh: line 2: `reg=[^/]+?(?=.zip)'
If I put the regex in a quotes, it no longer is recognized as regex. I have zsh 5.8 and bash 5.0.16 and it doesn't work on both shells.
How can I get bash to recognize the regex or not give me an error for using regex groups?
#!/bin/bash
regex='([^/.]+)([.]zip)?$'
path="/home/quid/Downloads/file.zip"
if [[ $path =~ $regex ]]
then
echo "Found a match"
echo "${BASH_REMATCH[1]}"
fi
Using Charles' regex and ${BASH_REMATCH[1]} gives me just the file name without the extension.

Bash regexp in if statement doesn't work [duplicate]

This question already has answers here:
How to match digits in regex in bash script
(2 answers)
Closed 6 years ago.
I'm trying to play with regular expressions in bash but i can't understand why this follow scenario doesn't work :
Regexp:
REGEXP="^(test\/)(([a-zA-Z]+)\-)+(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$"
String:
STRING="test/test-ods-1.10.1"
Test:
if [[ "$STRING" =~ $REGEXP ]]
then
echo "match!"
else
echo "don't match"
fi
Normally in this scenario I should receive a "match" but it's always returning a "doesn't match".
\d is not defined in bash regexps. Replace them with [0-9] and it'll work :
$ [[ "test/test-1.10.1" =~ ^(test\/)(([a-zA-Z]+)\-)+(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$ ]]; echo $?
1
$ [[ "test/test-1.10.1" =~ ^(test\/)(([a-zA-Z]+)\-)+(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; echo $?
0
No shorthand classes are defined in POSIX, and GNU extensions only bring a few of them, \w, \W, \s and \S according to regular-expressions.info.

Quoting regular expressions in Bash [duplicate]

This question already has answers here:
How do I use regular expressions in bash scripts?
(2 answers)
Closed 8 years ago.
I'm trying to write a condition that would fit all the lines starting with a space/tab and the word Path
/sPath.* - simple regexp?
I found that in Bash 4.* it should look like:
if [[ $LINE =~ "[[:space:]]Path" ]]
But this condition for some reason does not work.
if [[ $LINE =~ [[:space:]] ]]
work fine, and displays all lines with spaces/tabs.
From version 3.2 onwards, the pattern (i.e., the regular expression) must not be quoted in Bash:
New Features in Bash
...
f. Quoting the string argument to the [[ command's =~ operator now
forces string matching, as with the other pattern-matching operators.
In other words, quoting is considered part of the regular expression itself (literal ").
Moreover, it would be better to quote the variable $LINE, to prevent errors should it be empty:
if [[ "$LINE" =~ [[:space:]] ]]
It is better to use:
[[ "$LINE" =~ [[:blank:]] ]]
Quote the variable LINE
Match with character class [[:blank:]] which is equivalent of space OR tab

Bash regex match not working - escaping all special characters [duplicate]

This question already has answers here:
bash regex with quotes?
(5 answers)
Closed 3 years ago.
I'm having problem with bash regex match. I have regex like this:
re="fatal: file not found: .+/tmp_dir_1234/([^\ ]*) \(No such file or directory\)"
test="fatal: file not found: /some/path/irrelevant/something/tmp_dir_1234/somefile.txt (No such file or directory)"
if [[ "$test" =~ "$re" ]]; then
echo "match!"
fi
For me everything here looks good for now but for some reason while debugging bash script I can see that it doesn't match string here:
+ [[ fatal: file not found: /some/path/irrelevant/something/tmp_dir_1234/somefile.txt (No such file or directory) =~ fatal: file not found: \.\+/tmp_dir_1234/\(\[\^\\ ]\*\) \\\(No such file or directory\\\) ]]
For some reason regex pattern is escaped.
Remove the double quotes from the regular expression in the match:
if [[ "$test" =~ $re ]]; then
echo "match!"
fi
In double square brackets, there is no need to quote variables, as they are parsed in a special way. See man bash for details:
Word splitting and pathname expansion are not performed on the words between the [[ and ]]; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed.

Why isn't this regular expression test working? [duplicate]

This question already has answers here:
bash regex with quotes?
(5 answers)
Closed 9 years ago.
I have this
echo $line
Thisisaline.
I was wondering why is this not working:
if [[ "$line" =~ "[a-zA-Z]+\.$" ]] ; then echo "hello"; fi
Above regex gives no output.
The problem is that you are using quotes...
In bash regex, there is no need for quotes, and moreso, they should not be used (unless you are trying to match a quote (in which case you can escape it \")... Also if you want a space in your pattern, you must escape it, \  (there is a space after the back-slash ...
Also note, that to match the entire line as being alphabetic, you must add a leading ^ and a trailing $, otherwise it will match such lines as: 123 456 abc. cat and mouse
Try
if [[ $line =~ [a-zA-Z]+\. ]] ; then echo hello; fi
Some version of OS with bash gives you the output. So its up to you to get your updates.
However, without regex you can use extended globbing
shopt -s extglob
case "$line" in
+([a-zA-Z]). ) echo "hello";;
esac
if not, use regex without the quotes