基于空格和java中匹配引号的正则表达式拆分字符串

我有一个字符串,我需要根据空格和完全匹配的引号进行拆分。

如果

string = "It is fun \"to write\" regular\"expression" 

拆分后,我想要的结果是:

开玩笑

“来写”

定期

“表达

正常的表达式,我来到一些接近这样做的事情是:

 STRING_SPLIT_REGEXP = "[^\\s\"']+|\"([^\"]*)\"|'([^']*)'" 

提前谢谢你的答案。

看来你只是从这个答案中使用了正则表达式,但是你可以看到它不使用split而是从Matcher类中find方法。 此答案还会照顾'您的输入没有显示出来的迹象”。

因此,您可以通过删除部件处理来改进此正则表达式,这将使其看起来像

 [^\\s\"]+|\"([^\"]*)\" 

此外,因为你想要包含"作为令牌的一部分,然后你不需要在单独的组中放置匹配" ,所以摆脱\"([^\"]*)\"部分中的括号

 [^\\s\"]+|\"[^\"]*\" 

现在你需要做的就是添加没有关闭的情况" ,但你会得到字符串的结尾。所以改变这个正则表达式

 [^\\s\"]+|\"[^\"]*(\"|$) 

在此之后,您可以使用Matcher, find某处find所有商店令牌,让我们在List说。

例:

 String data = "It is fun \"to write\" regular\"expression"; List matchList = new ArrayList(); Pattern regex = Pattern.compile("[^\\s\"]+|\"[^\"]*(\"|$)"); Matcher regexMatcher = regex.matcher(data); while (regexMatcher.find()) { System.out.println(regexMatcher.group()); matchList.add(regexMatcher.group()); } 

输出:

 It is fun "to write" regular "expression 

处理此数据的更复杂表达式可能看起来像

 String data = "It is fun \"to write\" regular \"expression"; for(String s : data.split("(? 

但是这种方法过于复杂,然后编写自己的解析器。


这样的解析器可能看起来像

 public static List parse(String data) { List tokens = new ArrayList(); StringBuilder sb = new StringBuilder(); boolean insideQuote = false; char previous = '\0'; for (char ch : data.toCharArray()) { if (ch == ' ' && !insideQuote) { if (sb.length() > 0 && previous != '"') addTokenAndResetBuilder(sb, tokens); } else if (ch == '"') { if (insideQuote) { sb.append(ch); addTokenAndResetBuilder(sb, tokens); } else { addTokenAndResetBuilder(sb, tokens); sb.append(ch); } insideQuote = !insideQuote; } else { sb.append(ch); } previous = ch; } addTokenAndResetBuilder(sb, tokens); return tokens; } private static void addTokenAndResetBuilder(StringBuilder sb, List list) { if (sb.length() > 0) { list.add(sb.toString()); sb.delete(0, sb.length()); } } 

用法

 String data = "It is fun \"to write\" regular\"expression\"xxx\"yyy"; for (String s : parse(data)) System.out.println(s); 

您正在遇到正则表达式的基本限制。 一般来说,它们无法检测递归,深度等。

所以在你的字符串中:

 "It is fun \"to write\" regular\"expression" 

towrite之间的空间以及\"regular之间的空间都在引号内。 regular则表达式无法以灵活的方式”计算“引号数并基于它采取行动。

您需要为此编写自己的字符串解析器(或使用现有的字符串解析器)。 但是正则表达式无法处理它。

诀窍是使用灵活的前瞻来断言:

  • 如果输入中有偶数引号,则空格后面应该有一个偶数,因为奇数表示空格引号
  • 如果输入中有奇数个引号,则空格后面应该有一个奇数 ,因为偶数表示空格引号

我把它弄成了一行,但它是一个巨大的:

 String[] parts = str.split("(\\s+|(? 

这正确地拆分带有或不带尾随引号的示例字符串(尾部术语是否包含空格)。