基于空格和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"
to
和write
之间的空间以及\"
和regular
之间的空间都在引号内。 regular
则表达式无法以灵活的方式”计算“引号数并基于它采取行动。
您需要为此编写自己的字符串解析器(或使用现有的字符串解析器)。 但是正则表达式无法处理它。
诀窍是使用灵活的前瞻来断言:
- 如果输入中有偶数引号,则空格后面应该有一个偶数,因为奇数表示空格在引号内
- 如果输入中有奇数个引号,则空格后面应该有一个奇数 ,因为偶数表示空格在引号内
我把它弄成了一行,但它是一个巨大的:
String[] parts = str.split("(\\s+|(?
这正确地拆分带有或不带尾随引号的示例字符串(尾部术语是否包含空格)。