【问题标题】:Regular Expression: Capture Negation of Combination of Multiple Regular Expressions正则表达式:捕获多个正则表达式组合的否定
【发布时间】:2020-01-02 02:24:28
【问题描述】:

我有一个大的正则表达式,它结合了较小的正则表达式,我试图取反,以便捕获不在正则表达式中的字符(例如 ~、`、@、#、$、%、^、&)。

我尝试为我的错误情况编写一个正则表达式,但没有找到任何东西。也许这是因为正则表达式的顺序?此外,“!=”被认为是一个特殊符号,而“!”被认为是一个错误。我尝试使用负前瞻来解决这个问题(无济于事)。

...
String keyword = "\\b(?:else|if|int|return|void|while)\\b";
String identifier = "\\b[a-zA-Z]+\\b";
String number = "\\b[\\d]+\\b";
String special_symbol = "(==)|(!=)|(<=)|(>=)|(\\+)|(\\-)|(\\*)|(\\/)|(\\<)|(\\>)|(\\=)|(\\;)|(\\,)|(\\()|(\\))|(\\[)|(\\])|(\\{)|(\\})|(\\,)";
String error = "[_`~@#$%^&]|(!(?!(=)))";
String regex = "(" + keyword + ")|(" + identifier + ")|(" + number + ")|(" + special_symbol + ")|(" + error + ")";

Pattern pattern = Pattern.compile(regex);

for( Matcher matcher = pattern.matcher(str); matcher.find(); ) {
   if ( matcher.start(1) != -1 ) {
      System.out.println("Keyword: " + matcher.group() );
   } else if ( matcher.start(2) != -1 ) {
      System.out.println("ID: " + matcher.group() );
   } else if ( matcher.start(3) != -1 ) {
      System.out.println("NUM: " + matcher.group());
   } else if ( matcher.start(4) != -1 ) {
      System.out.println( matcher.group() );
   } else if ( matcher.start(5) != -1 ) {
      System.out.println("ERROR: " + matcher.group() );
   }
} // for
...

Expected Output:
INPUT: iiii = 3@33;
ID: iiii 
=
NUM: 3
Error: @33
;

Actual Output:
INPUT: iiii = 3@33;
ID: iiii
=
NUM: 3
NUM: 33
;

Expected Output:
INPUT: else ret_urn gcd(vxxxxxxvvvvv, u-u/v*v);
keyword: else
ID: ret
Error: _urn
ID: gcd
(
ID: vxxxxxxvvvvv
,
ID: u
-
ID: u
/
ID: v
*
ID: v
)
;

Actual Output:
INPUT: else ret_urn gcd(vxxxxxxvvvvv, u-u/v*v);
Keyword: else
ID: gcd
(
ID: vxxxxxxvvvvv
,
ID: u
-
ID: u
/
ID: v
*
ID: v
)
;

Expected Output:
INPUT: !
Error: !

Actual Output:
INPUT: !
(This is supposed to be an error, but nothing is captured)

【问题讨论】:

  • 很高兴看到一些输入通过或失败。甚至是正则表达式输出,因为 Java 不在我的机器上运行。
  • @sln "..." 之后的所有内容都是输入示例。您需要更多输入示例吗?
  • 您希望(!(?!(=))) 做什么? ! 后面没有=?为什么? ! (NOT) 运算符应该是有效的“special_symbol”,不是吗? --- 不管怎样,这两个不必要的捕获组太长了,所以只需使用!(?!=)
  • error 只抓取一个尚未与早期表达式匹配的非空白字符不是更容易吗?如error = "\\S"
  • 哇。我不知道捕获组会导致这么多问题,下次我一定会尽量少用它们。另外,是的。 "\\S+" 是错误和令牌的其余部分。非常感激!再次感谢!

标签: java regex regex-lookarounds regex-negation regex-group


【解决方案1】:

keywordidentifiernumber 未定义任何捕获组,因此 regexkeyword 定义为组 1,identifier 定义为组 2,number 定义为组 3,以及special_symbol 作为第 4 组。

然而,由于special_symbol 定义了许多捕获组,所以第5 组是(==)。它不是regex 中的第五个()。由于special_symbol 中有 20 个捕获组,这意味着 error 是第 25 个组,但不要使用它(太容易出错,未来更改)。

special_symbol 中删除所有捕获组:

String special_symbol = "==|!=|<=|>=|\\+|\\-|\\*|\\/|\\<|\\>|\\=|\\;|\\,|\\(|\\)|\\[|\\]|\\{|\\)|\\,";

哦,哎呀,\\,\\) 都在其中两次,但没有 \\}

此外,所有这些单个特殊字符都应该在一个字符类中,而不是在一个大的 OR 序列中:

String special_symbol = "==|!=|<=|>=|[+\\-*/<>=;,()\\[\\]{}]";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    相关资源
    最近更新 更多