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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/917822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:03:02  来源:igfitidea点击:

Tokenizing Error: java.util.regex.PatternSyntaxException, dangling metacharacter '*'

javaregexsplittokenize

提问by andandandand

I am using split()to tokenize a String separated with *following this format:

我正在使用以下格式split()对字符串进行标记化*

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

I'm reading this from a file named "entrada.al" using this code:

我正在使用以下代码从名为“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();
    }

And I'm getting this exception:

我得到这个例外:

Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0 *

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

My guess is that the lack of a *after age on the original text file is causing this. How do I get around it?

我的猜测是*原始文本文件中缺少after age 导致了这种情况。我该如何解决?

采纳答案by Michael Myers

No, the problem is that *is a reserved character in regexes, so you need to escape it.

不,问题在于它*是正则表达式中的保留字符,因此您需要对其进行转义。

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

*means "zero or more of the previous expression" (see the PatternJavadocs), and you weren't giving it any previous expression, making your split expression illegal. This is why the error was a PatternSyntaxException.

*表示“前一个表达式的零个或多个”(请参阅PatternJavadocs),并且您没有为其提供任何前一个表达式,从而使您的拆分表达式非法。这就是为什么错误是一个PatternSyntaxException.

回答by jdc0589

The first answer covers it.

第一个答案涵盖了它。

Im guessing that somewhere down the line you may decide to store your info in a different class/structure. In that case you probably wouldn't want the results going in to an array from the split() method.

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

You didn't ask for it, but I'm bored, so here is an example, hope it's helpful.

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

This might be the class you write to represent a single person:

这可能是您为代表一个人而编写的类:


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.
} 

Then, the version of the parsing code you originally posted would look something like this: (This stores them in a LinkedList, you could use something else like a Hashtable, etc..)

然后,您最初发布的解析代码的版本将如下所示:(这将它们存储在 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();
}

回答by Vishal Joshi

It is because * is used as a metacharacter to signify one or more occurences of previous character. So if i write M* then it will look for files MMMMMM..... ! Here you are using * as the only character so the compiler is looking for the character to find multiple occurences of,so it throws the exception.:)

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

回答by Aniket Thakur

I had similar problem with regex = "?". It happens for all special characters that have some meaning in a regex. So you need to have "\\"as a prefix to your regex.

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

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