Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

match a line using bash regex

Tags:

regex

bash

I want to match a line that contains a word, but does not have semi-colon in it

This should match:

class test

this should not match

class test;

this should not match either

class test; // test class

this is what I was expecting to work, but it doesn't:

pattern="class [^;]*"

if [[ $line =~ $pattern ]]

thanks

like image 900
ewrgq3er Avatar asked Oct 02 '22 00:10

ewrgq3er


2 Answers

Your regular expression is not anchored which means that [^;]* will still match against all characters up to a possible ; (and thus match as a whole). If you anchor the regex against the end of the line ([^;]*$) it will produce the results you are after:

$ cat t.sh
#!/bin/bash

pattern='class [^;]*$'
while read -r line; do
    printf "testing '${line}': "
    [[ $line =~ $pattern ]] && echo matches || echo "doesn't match"
done <<EOT
class test
class test;
class test; // test class
EOT

$ ./t.sh
testing 'class test': matches
testing 'class test;': doesn't match
testing 'class test; // test class': doesn't match

TL;DR: In other words, the bold part in

class test; foo bar quux

matches your regex even though the string contains a semicolon which is why it always matches. The anchor makes sure that the regular expression only matches if there is no semicolon until the very end of the string.

like image 199
Adrian Frühwirth Avatar answered Oct 09 '22 13:10

Adrian Frühwirth


how about straightforwardly:

 pattern="^[^;]*\bclass\b[^;]*$"

\b word boundary was added, for matching xxx class xxx only, not matching superclass xxx

like image 31
Kent Avatar answered Oct 09 '22 12:10

Kent