标记化错误:java.util.regex.PatternSyntaxException,悬空元字符“*”

Posted

技术标签:

【中文标题】标记化错误:java.util.regex.PatternSyntaxException,悬空元字符“*”【英文标题】:Tokenizing Error: java.util.regex.PatternSyntaxException, dangling metacharacter '*' 【发布时间】:2010-10-29 09:41:40 【问题描述】:

我正在使用split() 来标记一个用* 分隔的字符串,格式如下:

name*lastName*ID*school*age
%
name*lastName*ID*school*age
%
name*lastName*ID*school*age

我正在使用以下代码从名为“entrada.al”的文件中读取此内容:

static void leer() 

    try 
        String ruta="entrada.al";
        File myFile = new File (ruta);
        FileReader fileReader = new FileReader(myFile);

        BufferedReader reader = new BufferedReader(fileReader);

        String line = null;

        while ((line=reader.readLine())!=null)
            if (!(line.equals("%")))
                String [] separado = line.split("*"); //SPLIT CALL
                names.add(separado[0]);
                lastNames.add(separado[1]);
                ids.add(separado[2]);
                ages.add(separado[3]);
            
        

        reader.close();
    

我得到了这个例外:

线程“main”中的异常 java.util.regex.PatternSyntaxException:在索引 0 附近悬空元字符 '*' *

我的猜测是原始文本文件在年龄后缺少* 导致了这种情况。我该如何解决?

【问题讨论】:

【参考方案1】:

不,问题是*是正则表达式中的保留字符,所以你需要转义它。

String [] separado = line.split("\\*");

* 表示“前一个表达式的零个或多个”(参见Pattern Javadocs),并且您没有给它任何前一个表达式,从而使您的拆分表达式非法。这就是为什么错误是 PatternSyntaxException

【讨论】:

【参考方案2】:

regex = "?" 也有类似的问题。它发生在所有在正则表达式中具有某些含义的特殊字符上。因此,您需要将 "\\" 作为正则表达式的前缀。

String [] separado = line.split("\\*");

【讨论】:

【参考方案3】:

第一个答案涵盖了它。

我猜你可能会决定将你的信息存储在不同的类/结构中。在这种情况下,您可能不希望结果从 split() 方法进入数组。

你没有要求,但我很无聊,所以这里是一个例子,希望它有帮助。

这可能是你写的代表一个人的类:

class Person public String firstName; public String lastName; public int id; public int age; public Person(String firstName, String lastName, int id, int age) this.firstName = firstName; this.lastName = lastName; this.id = id; this.age = age; // Add 'get' and 'set' method if you want to make the attributes private rather than public.

然后,您最初发布的解析代码版本将如下所示: (这会将它们存储在 LinkedList 中,您可以使用其他东西,例如 Hashtable 等。)

try String ruta="entrada.al"; BufferedReader reader = new BufferedReader(new FileReader(ruta)); LinkedList<Person> list = new LinkedList<Person>(); String line = null; while ((line=reader.readLine())!=null) if (!(line.equals("%"))) StringTokenizer st = new StringTokenizer(line, "*"); if (st.countTokens() == 4) list.add(new Person(st.nextToken(), st.nextToken(), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken))); else // whatever you want to do to account for an invalid entry // in your file. (not 4 '*' delimiters on a line). Or you // could write the 'if' clause differently to account for it reader.close();

【讨论】:

【参考方案4】:

这是因为 * 用作元字符来表示前一个字符的一个或多个出现。所以如果我写 M* 那么它会寻找文件 MMMMMM .....!在这里,您使用 * 作为唯一字符,因此编译器正在寻找该字符以查找多个出现的位置,因此它会引发异常。:)

【讨论】:

以上是关于标记化错误:java.util.regex.PatternSyntaxException,悬空元字符“*”的主要内容,如果未能解决你的问题,请参考以下文章

hive ngram使用什么分隔符来标记化?

Weka POS 标记 + 标记化

使用标记化有啥意义?

如何在 Sanity 中定义标记化标签字段?

如何实现 XSLT 标记化功能?

Objective-C 中的 NSString 标记化