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

时间:2009-05-27 20:18:55

标签: java regex split tokenize

我正在使用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附近悬挂元字符'*'   *

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

4 个答案:

答案 0 :(得分:136)

不,问题是*是正则表达式中的保留字符,因此您需要将其转义。

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

*表示“前一个表达式的零个或多个”(请参阅​​Pattern Javadocs),并且您没有给它任何先前的表达式,使得您的拆分表达式非法。这就是错误为PatternSyntaxException的原因。

答案 1 :(得分:6)

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

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

答案 2 :(得分: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();
}

答案 3 :(得分:2)

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