Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中解析字符串的有效方法是什么?_Java_Regex_String_Parsing - Fatal编程技术网

在Java中解析字符串的有效方法是什么?

在Java中解析字符串的有效方法是什么?,java,regex,string,parsing,Java,Regex,String,Parsing,我应该如何使用Java解析以下字符串来提取文件路径 ?表示任意数量的随机字符 表示任意数量的空格(无新行) 例如: 10:52:21.212 [LoadFile] file = "foo/bar/baz.xml" 应该提取foo/bar/baz.xml是你的朋友 String regex = ".*\\[LoadFile\\]\\s+file\\s+=\\s+\"([^\"].+)\".*"; Matcher m = Pattern.compile(regex).matcher(inputS

我应该如何使用Java解析以下
字符串
来提取文件路径

表示任意数量的随机字符

表示任意数量的空格(无新行)

例如:

10:52:21.212 [LoadFile] file = "foo/bar/baz.xml"
应该提取
foo/bar/baz.xml

是你的朋友

String regex = ".*\\[LoadFile\\]\\s+file\\s+=\\s+\"([^\"].+)\".*";

Matcher m = Pattern.compile(regex).matcher(inputString);
if (!m.find()) 
    System.out.println("No match found.");
else
    String result = m.group(1);
结果中的
字符串
应该是您的文件路径。(假设我没有犯任何错误)


您应该查看该类以获得一些正则表达式帮助。它们可以是一个非常强大的字符串操作工具。

您可以使正则表达式比jinguy的稍短一点。基本上只有RHS没有“'s”


虽然正则表达式很好,但您也可以使用class
java.util.StringTokenizer
来完成这项工作。其优点是代码更人性化

StringTokenizer tokenizer = new StringTokenizer(inputString, "\"");
tokenizer.nextElement();
String path = tokenizer.nextElement();
这就是答案。

简单回答:使用subSequence()

在我的机器上,这始终不到10000纳秒

我把“高效”理解为更快

regex选项的速度要慢得多(大约慢9到10倍)。regex选项的主要优点是,其他程序员可能更容易理解您在做什么(但随后使用注释来帮助他们)

要使regex选项更有效,请预编译它:

private static final String FILE_REGEX = ".*\\[LoadFile\\]\\s+file\\s+=\\s+\"([^\"].+)\".*";
private static final Pattern FILE_PATTERN = Pattern.compile(FILE_REGEX);
但这仍然让它变慢。我记录的时间在80000到100000纳秒之间

StringTokenizer选项比正则表达式更有效:

if (line.contains("[LoadFile]")) {
  StringTokenizer tokenizer = new StringTokenizer(line, "\"");
  tokenizer.nextToken();
  result = tokenizer.nextToken();
}
这对我来说大约是40000ns,比正则表达式快2-3倍

在这个场景中,split()也是一个选项,对我来说(使用Java 6_13)只比标记器快一点:

if (line.contains("[LoadFile]")) {
  String[] values = line.split("\"");
  result = values[1];
}
这对我来说平均是35000纳秒


当然,这些都不是在检查错误。当你开始考虑错误时,每个选项都会慢一点,但我认为subsquince()选项仍然会击败所有选项。你必须知道确切的参数和期望值,以确定每个选项需要有多大的容错性。

“*\[LoadFile\]\\sfile\\s*=\\s\([^\\\\\\].*.””最好匹配任意数量的空格。“*\”([^\\“].*)\“*”会更好,因为我们根本不关心前缀格式(默认情况下已知),并且它不包含任何引号。仅供参考,Jean的正则表达式也不匹配任何空格,例如[LoadFile]file=“foo/bar/baz.xml“。因此,如果您至少需要一个空格字符,请使用+而不是最初指定的*作为jinguy。@weenaak:我会将“任意数量的空格”理解为包含零的任意数字。两个更正:创建Matcher对象的方法是
。Matcher(inputString)
(不大写),您必须通过在Matcher上调用
.matches()
.find()
来应用正则表达式。我认为jinguy认为只有在行中有[LoadFile]时才应该提取路径……当我编写正则表达式时,我会尽量具体。有些人在遇到堆栈溢出问题时,会回答“java.util.regex是你的朋友”现在问这个问题的人有两个问题--如果你打算建议使用正则表达式,请举个例子。@Grant Wagner我认为把人们引向正确的方向并没有什么错,即使我没有时间想出一个完整的解决方案。如果你对答案不满意,那么就给出一个更好的答案,而不是浪费时间抱怨。StringTok的另一个优点是enizer的意思是,如果它能够完成手头的工作,那么它可能会更高效。只是如果第一组随机字符中碰巧有一些“字符”,那么标记器会很高兴地将其作为下一个元素返回。然而,该示例表明输入行的第一部分只是一个时间戳。正则表达式更难编写,但更能处理完全不同的输入。我同意StringTokenizer并不是解决所有解析问题的理想方案,但在我看来,使用正则表达式有点像用大炮捕杀苍蝇。。。
private static final String FILE_REGEX = ".*\\[LoadFile\\]\\s+file\\s+=\\s+\"([^\"].+)\".*";
private static final Pattern FILE_PATTERN = Pattern.compile(FILE_REGEX);
if (line.contains("[LoadFile]")) {
  StringTokenizer tokenizer = new StringTokenizer(line, "\"");
  tokenizer.nextToken();
  result = tokenizer.nextToken();
}
if (line.contains("[LoadFile]")) {
  String[] values = line.split("\"");
  result = values[1];
}