【问题标题】:regex exclude a character not work正则表达式排除一个字符不起作用
【发布时间】:2015-10-25 14:14:18
【问题描述】:

我想从 java 文件中获取类名。例如

class Mango {

现在我想将mango 作为类名。

这是我使用的正则表达式

\s*class\s+(\S+)

它有效,我捕获了类名。问题是如果类名在类名和右花括号之间没有空格,我得到的名字是mango{

如下图。

class Mango{

所以我想从组中排除{。所以我修改为关注

\s*class\s+(\S+|[^{])

但它不起作用并且仍然用右括号捕获类名。我怎样才能只得到类名。

【问题讨论】:

    标签: java regex


    【解决方案1】:

    要仅接受可用作类或变量名称的正确字符,我们可能需要使用方法Character.isJavaIdentifierPart,可以通过\p{javaJavaIdentifierPart} 引用,如Pattern class documentation 中所述(强调我的):

    行为类似于java.lang.Character boolean is<b>MethodName</b> 方法的类别(已弃用的方法除外)可通过相同的\p{property} 语法获得,其中指定的property 具有名称java<b><i>MethodName</i></b>

    演示:

    String text = "class Mango{";
    
    Pattern p = Pattern.compile("\\s*class\\s+(\\p{javaJavaIdentifierPart}+)");
    Matcher m = p.matcher(text);
    
    if (m.find()){
        System.out.println(m.group(1));
    }else{
        System.out.println("no match found");
    }
    

    输出:Mango


    如果你不打算在 Java 引擎中使用这个正则表达式,那么你可以使用 [^\s{] 而不是 \S 喜欢

    \s*class\s+([^\s{]+)
    

    它将接受除空格和{之外的任何字符。

    【讨论】:

    • 你的意思是这样吗?? \s*class\s+([^\s{]+|[^{])
    • @whiletrue 再次更新答案以包含\p{javaJavaIdentifierPart},这似乎是Java 正则表达式中处理这种情况的最佳工具。
    【解决方案2】:

    试试这个正则表达式:

    class\s+([\w$]+)
    

    \w - 是一个单词字符 (a-zA-Z0-9_)

    这个正则表达式将只捕获类名允许的字符。但是,如果我们假设 coder 使用了有效字符,您也可以尝试:

    (?<=class\s)\s*(.+?)(?=\s*\{)
    

    DEMO

    这是:

    • (?&lt;=class\s) - 单词类和空格的正向回溯,
    • \s*(.+?) - 零个或多个空格,以及一个或多个字符,
    • (?=\s*\{) - whitspace(s) 和大括号的正向前瞻 {

    直接获取类名。此正则表达式允许所有字符,但如果编码器使用 Java 名称中允许的很少使用的 characters 之一,它可能会很有用。

    【讨论】:

    • 最好是匹配 Java 标识符规则的正则表达式,IIRC:class\s+([a-zA-Z_]\w*)(标识符以字母或下划线字符开头,后跟零个或多个字母数字(或下划线)。(可能更好更好地使用 Unicode 字符类:我不记得 Java 标识符是否可以使用 ASCII 以外的字符)。
    • \w 的问题是它不会匹配所有可以在类名中使用的可能字符,例如$
    • @m.cekiera 谢谢,但(?&lt;=class\s)\s*(.+)(?=\s+\{) 没有从class mango{ 捕获芒果
    • @whiletrue 对不起,我的明显错误,我认为名称后总会有空格,我更新了答案
    【解决方案3】:

    不确定问题是什么:您是否想要解释 (a) 为什么您的方法不起作用,或者您想知道 (b) 这个问题的正确正则表达式是什么样的?

    如果是后者,其他答案和cmets已经提供了一些正确的表达方式。如果是前者,那么考虑一下

    (\S+|[^{])
    

    实际上匹配。这基本上是说:匹配不是空格的所有内容不是左花括号。注意那个句子中的“或”。

    您的表达式仍然匹配“Mango”之后的{ 的原因是它满足句子的第一部分:{ 不是空格,因此您的正则表达式匹配。同样的论点适用于“Mango”和{之间的空格:它满足“不是左大括号”部分,因此也匹配。

    你想要的是一个编码的表达式:匹配所有不是空格的东西并且不是左花括号。如上所述,此问题的其他答案/cmets 显示了有关如何实现此目的的示例。

    【讨论】:

      猜你喜欢
      • 2021-10-27
      • 1970-01-01
      • 2021-09-16
      • 2014-09-28
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      • 2012-02-17
      相关资源
      最近更新 更多