Prashant Gupta
Prashant Gupta

Reputation: 163

Grep regex not working with square brackets

So I was trying to write a regex in grep to match square brackets, i.e [ad] should match [ and ]. But I was getting different results on using capturing groups and character classes. Also the result is different on putting ' in the beginning and end of regex string.

So these are the different result that I am getting.

Using capturing groups works fine

echo "[ad]" | grep -E '(\[|\])'
[ad]

Using capturing groups without ' gives syntax error

echo "[ad]" | grep -E (\[|\])
bash: syntax error near unexpected token `('

using character class with [ followed by ] gives no output

echo "[ad]" | grep -E [\[\]]

Using character class with ] followed by [ works correctly

echo "[ad]" | grep -E [\]\[]
[ad]

Using character class with ] followed by [ and using ' does not work

echo "[ad]" | grep -E '[\]\[]'

It'd be great if someone could explain the difference between them.

Upvotes: 3

Views: 7579

Answers (3)

Shakiba Moshiri
Shakiba Moshiri

Reputation: 23774

You should know about:

BRE ( = Basic Regular Expression )

ERE ( = Extended Regular Expression )


BRE metacharacters require a backslash to give them their special meaning and grep is based on

The ERE flavor standardizes a flavor similar to the one used by the UNIX egrep command.


Pay attention to -E and -G

grep --help
Usage: grep [OPTION]... PATTERN [FILE]...
Search for PATTERN in each FILE or standard input.
PATTERN is, by default, a basic regular expression (BRE).
Example: grep -i 'hello world' menu.h main.c

Regexp selection and interpretation:
  -E, --extended-regexp     PATTERN is an extended regular expression (ERE)
  -F, --fixed-strings       PATTERN is a set of newline-separated strings
  -G, --basic-regexp        PATTERN is a basic regular expression (BRE)
  -P, --perl-regexp         PATTERN is a Perl regular expression
  ...
  ...

POSIX Basic Regular Expressions

POSIX Extended Regular Expressions

POSIX Bracket Expressions


And you should also know about , since some of your input is related to bash interpreter not grep or anything else

echo "[ad]" | grep -E (\[|\])

Here assumes you try to use () something like:

echo $(( 10 * 10 ))

and by using single quote ' you tell the that you do not want it treats as a special operator for it. So

echo "[ad]" | grep -E '(\[|\])'

is correct.

Upvotes: 5

randomir
randomir

Reputation: 18687

Maybe you provided such a simple example on purpose (after all, it is minimal), but in case all you really want is to check for existence of square brackets (a fixed string, not regex pattern), you can use grep with -F/--fixed-strings and multiple -e options:

$ echo "[ad]" | grep -F -e '[' -e ']'
[ad]

Or, a little bit shorter with fgrep:

$ echo "[ad]" | fgrep -e '[' -e ']'
[ad]

Or, even:

$ echo "[ad]" | fgrep -e[ -e]
[ad]

Upvotes: 0

heemayl
heemayl

Reputation: 41987

Firstly, always quote Regex pattern to prevent shell interpretation beforehand:

$ echo "[ad]" | grep -E '(\[|\])'
[ad]

Secondly, within [] surrounded by quotes, you don't need to escape the [] inside, just write them as is within the outer []:

$ echo "[ad]" | grep -E '[][]'
[ad]

Upvotes: 0

Related Questions