我已经在stackoverflow上搜索了几篇关于如何在逗号分隔符上拆分字符串的帖子,但忽略了引号中逗号的拆分(参见:How do I split a string into an array by comma but ignore commas inside double quotes?)我试图实现类似的结果,但还需要允许包含一个双引号的字符串。
IE。需要"test05, \"test, 05\", test\", test 05"
分成
test05
"test, 05"
test"
test 05
我尝试了类似于这里提到的方法:
Regex for splitting a string using space when not surrounded by single or double quotes
使用匹配器而不是split()
。但是,它的具体例子是在空格上分割,而不是在逗号上。我试图调整模式以说明逗号,但是没有运气。
String str = "test05, \"test, 05\", test\", test 05";
str = str + " "; // add trailing space
int len = str.length();
Matcher m = Pattern.compile("((\"[^\"]+?\")|([^,]+?)),++").matcher(str);
for (int i = 0; i < len; i++)
{
m.region(i, len);
if (m.lookingAt())
{
String s = m.group(1);
if ((s.startsWith("\"") && s.endsWith("\"")))
{
s = s.substring(1, s.length() - 1);
}
System.out.println(i + ": \"" + s + "\"");
i += (m.group(0).length() - 1);
}
}
答案 0 :(得分:1)
你已经达到正则表达式崩溃的程度。
我建议您编写一个简单的拆分器来处理您的 希望的特殊情况。测试驱动开发非常适合这样做。
但是,它看起来像是在尝试解析CSV行。您是否考虑过使用CSV库?答案 1 :(得分:1)
我对此有类似的问题,而且我发现没有好的.net解决方案,所以去了DIY。
在我的应用程序中,我正在解析csv,因此我的拆分凭证是&#34;,&#34;。我想这个方法只适用于你有一个char split参数的地方。
所以,我编写了一个忽略双引号内逗号的函数。它通过将输入字符串转换为字符数组并通过char
解析char来实现public static string[] Splitter_IgnoreQuotes(string stringToSplit)
{
char[] CharsOfData = stringToSplit.ToCharArray();
//enter your expected array size here or alloc.
string[] dataArray = new string[37];
int arrayIndex = 0;
bool DoubleQuotesJustSeen = false;
foreach (char theChar in CharsOfData)
{
//did we just see double quotes, and no command? dont split then. you could make ',' a variable for your split parameters I'm working with a csv.
if ((theChar != ',' || DoubleQuotesJustSeen) && theChar != '"')
{
dataArray[arrayIndex] = dataArray[arrayIndex] + theChar;
}
else if (theChar == '"')
{
if (DoubleQuotesJustSeen)
{
DoubleQuotesJustSeen = false;
}
else
{
DoubleQuotesJustSeen = true;
}
}
else if (theChar == ',' && !DoubleQuotesJustSeen)
{
arrayIndex++;
}
}
return dataArray;
}
对于我的应用程序,这个函数在任何输入中都会忽略(&#34;&#34;),因为这些不需要并存在于我的输入中。
答案 2 :(得分:0)
反对这种模式:
(?<=\"?),(?!\")|(?<!\"),(?=\")
所以它将是:
String[] splitArray = subjectString.split("(?<=\"?),(?!\")|(?<!\"),(?=\")");
UPD:根据问题逻辑的最近变化,最好不要使用裸分割,首先应该用逗号分隔逗号中的文本,然后在最后一个上进行简单分割(“,”)。只需使用简单的for循环并检查你遇到多少引号,同时将你读过的字符保存到StringBuffer中。首先将字符保存到StringBuffer中,直到遇到引号,然后将StringBuffer放入包含不在引号中的字符串的数组中。然后你创建新的StringBuffer并保存你读入的下一个字符,在你遇到第二个逗号后,你停止并将你的新StringBuffer放入包含逗号字符串的数组中。重复直到字符串结束。因此,您将拥有2个数组,一个使用逗号处理的字符串,另一些字符串不是逗号。然后你应该拆分第二个数组的所有元素。
答案 3 :(得分:0)
除非你真的需要DIY,否则你应该考虑使用Apache Commons类org.apache.commons.csv.CSVParser
http://commons.apache.org/sandbox/csv/apidocs/org/apache/commons/csv/CSVParser.html
答案 4 :(得分:0)
试试这个:
import java.util.regex.*;
public class Main {
public static void main(String[] args) throws Exception {
String text = "test05, \"test, 05\", test\", test 05";
Pattern p = Pattern.compile(
"(?x) # enable comments \n" +
"(\"[^\"]*\") # quoted data, and store in group #1 \n" +
"| # OR \n" +
"([^,]+) # one or more chars other than ',', and store it in #2 \n" +
"| # OR \n" +
"\\s*,\\s* # a ',' optionally surrounded by space-chars \n"
);
Matcher m = p.matcher(text);
while (m.find()) {
// get the match
String matched = m.group().trim();
// only print the match if it's group #1 or #2
if(m.group(1) != null || m.group(2) != null) {
System.out.println(matched);
}
}
}
}
对于test05, "test, 05", test", test 05
,它会产生:
test05 "test, 05" test" test 05
并且test05, "test 05", test", test 05
产生:
test05 "test 05" test" test 05