令牌化错误:java.util.regex.PatternSyntaxException,悬而未决的元字符“*”
我使用split()
来标记用*
分隔的string,格式如下:
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”中的exceptionjava.util.regex.PatternSyntaxException:在索引0附近悬挂元字符'*'
我的猜测是,在原始文本文件的年龄之后缺less*
是造成这种情况的原因。 我如何解决它?
不,问题是*
是正则expression式中的保留字符,所以您需要将其转义。
String [] separado = line.split("\\*");
*
表示“零或多个以前的expression式”(请参阅Pattern
Javadocs ),并且您没有给它以前的expression式,使您的分割expression式非法。 这就是为什么这个错误是PatternSyntaxException
。
我有类似的问题与regex = "?"
。 在正则expression式中,所有特殊字符都有一些意义。 所以你需要有"\\"
作为你的正则expression式的前缀。
String [] separado = line.split("\\*");
第一个答案涵盖了它。
我猜测你可能会决定将你的信息存储在不同的类/结构中。 在这种情况下,你可能不希望结果从split()方法进入数组。
你没有要求,但我很无聊,所以这里是一个例子,希望有帮助。
这可能是你写的代表一个人的class级:
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. }
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. }
然后,您最初发布的parsing代码的版本将如下所示:(这将它们存储在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(); }
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(); }
这是因为*被用作元字符来表示前一个字符的一个或多个出现。 所以,如果我写M *,那么它会寻找文件MMMMMM …..! 这里你使用*作为唯一的字符,所以编译器正在寻找字符来查找多个事件,所以它会抛出exception。