5

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

2
  • 1
    What about class test // test class; ? Commented Apr 15, 2014 at 13:23
  • Do not edit this question with your new question or remove details from this question that has answers. Use the Ask Question button and post a new question providing all of the details needed to get your answer Commented May 6, 2014 at 11:46

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

Comments

1

how about straightforwardly:

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

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

Comments

0

Use ^[^;]+($|\s*//). This means any number of non-semicolon characters (at least one) from the start of the string until either the end of the line or any number of spaces followed by two slashes.

http://rubular.com/r/HTizIXz2HA

Comments

0

I think you need:

pattern="^[^;]*class [^;]*$"`

This ensures the line don't have a ; before or after your [^;]* match.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.