什么是正则表达式打印没有你指定的单词的行?

时间:2013-05-31 05:59:21

标签: regex

我有这个输出:

---------- snippet start ----------
JUnit version 4.11
I.E
Time: 0.015
There was 1 failure:
1) testPerson(PersonTest)
org.junit.ComparisonFailure: expected:<John[1]> but was:<John[]>
    at org.junit.Assert.assertEquals(Assert.java:115)
    at org.junit.Assert.assertEquals(Assert.java:144)
    at PersonTest.testPerson(PersonTest.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)

---------- snippet end----------

我想只检索每行开头没有单词“at”的行,但不包括包含单词“PersonTest.java”的行(带“at”) 非常感谢你!

3 个答案:

答案 0 :(得分:2)

如果IDE的正则表达式引擎支持它,那么规范方法是使用否定先行断言:

(?!^\s*at\b)

(我在那里放了一个单词边界,以防一行开头,比如“附加”。)

但是如果IDE 不支持支持环绕声断言,那么你必须做一些类似于@HamZa建议的事情。 @ HamZa的解决方案虽然有点偏,但是,例如,它也会过滤掉以“as”开头的行。这是正确的:

^\s*([^a\s]|a[^t])

换句话说,在忽略前导空格后,如果你的第一个角色是而不是一个a,那么你很高兴去 - 别的,你只需要确保第二个角色字符不是t

现在,这并未考虑“附加”案件。加上这个:

^\s*([^a\s]|a[^t]|at\w)

tl; dr 这是一个无论如何都应该有效的正则表达式:

^[ \t]*([^a\s]|a[^t]|at[a-zA-Z0-9_])

答案 1 :(得分:1)

如果你不介意该组捕获并且不能使用前瞻,你可以使用这个正则表达式:

^((\s{4}|\t)*([^a]t|a[^t]|at[^\s]+)|[^\s]+).*

您可以在行动here中看到它。

问题在于很难匹配at,因为\s*会立即重新调整以允许显式的非at字符。例如:

at

\s*[^a][^t]不匹配,但会匹配:

 at
123

1是第一个[^a]匹配; 2是[^t]匹配。并且\s*只是将其最大匹配减少到(最大-1)匹配。

所以,这就是为什么你会在我的正则表达式中找到\s{4}来阻止运算符*的回溯。

现在,我使用[^a]t|a[^t]|at[^\s]+来阻止与at的匹配,允许其他所有内容并允许某些特定匹配:

a t
attention

应该匹配,因为没有文字at

答案 2 :(得分:0)

所以,换句话说,你想过滤掉所有堆栈跟踪线,除了那些与测试类本身有关的线路,对吧?!

您需要一个支持否定前瞻的正则表达式引擎,例如GNU grep支持-P / --perl-regexp

grep -v -P '^ *at (?!.*PersonTest)' output

这会过滤掉(-v)所有以at开头的行,,后面跟PersonTest