使用bash正则表达式匹配一行

时间:2022-09-13 08:31:09

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

4 个解决方案

#1


3  

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

TL; DR:换句话说,大胆的部分

class test; foo bar quux

班级考试; 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.

匹配你的正则表达式,即使字符串包含分号,这就是它总是匹配的原因。锚点确保正则表达式只有在字符串的最后才有分号时才匹配。

#2


1  

how about straightforwardly:

怎么样直截了当:

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

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

\ b添加了单词边界,仅用于匹配xxx类xxx,不匹配超类xxx

#3


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.

使用^ [^;] +($ | \ s * //)。这意味着从字符串的开头到行的末尾或任意数量的空格后跟两个斜杠的任意数量的非分号字符(至少一个)。

http://rubular.com/r/HTizIXz2HA

#4


0  

I think you need:

我认为你需要:

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

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

这确保了生产线没有;在[^;] *匹配之前或之后。

#1


3  

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

TL; DR:换句话说,大胆的部分

class test; foo bar quux

班级考试; 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.

匹配你的正则表达式,即使字符串包含分号,这就是它总是匹配的原因。锚点确保正则表达式只有在字符串的最后才有分号时才匹配。

#2


1  

how about straightforwardly:

怎么样直截了当:

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

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

\ b添加了单词边界,仅用于匹配xxx类xxx,不匹配超类xxx

#3


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.

使用^ [^;] +($ | \ s * //)。这意味着从字符串的开头到行的末尾或任意数量的空格后跟两个斜杠的任意数量的非分号字符(至少一个)。

http://rubular.com/r/HTizIXz2HA

#4


0  

I think you need:

我认为你需要:

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

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

这确保了生产线没有;在[^;] *匹配之前或之后。