1

我在stackoverflow上搜索了几篇关于如何在逗号分隔符上拆分字符串的帖子,但忽略了引号中的逗号拆分(请参阅:如何通过逗号将字符串拆分为数组但忽略双引号内的逗号?)我正在尝试以达到类似的结果,但还需要允许包含一个双引号的字符串。

IE。需要"test05, \"test, 05\", test\", test 05"拆分成

  • test05
  • "test, 05"
  • test"
  • test 05

我尝试了与此处提到的方法类似的方法:

正则表达式用于在没有被单引号或双引号包围时使用空格分割字符串

使用 Matcher,而不是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);
    }
}
4

5 回答 5

1

你已经到了正则表达式崩溃的地步。

我建议您编写一个简单的拆分器来处理您的特殊情况。测试驱动开发非常适合这样做。

但是,看起来您正在尝试解析 CSV 行。您是否考虑过为此使用 CSV 库?

于 2011-05-11T18:29:59.650 回答
1

我也遇到过类似的问题,而且我没有找到好的 .net 解决方案,所以就自己动手做了。

在我的应用程序中,我正在解析一个 csv,所以我的拆分凭证是“,”。我想这种方法只适用于你有一个 char split 参数的地方。

因此,我编写了一个忽略双引号内逗号的函数。它通过将输入字符串转换为字符数组并逐字符解析字符来实现

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;
    }

根据我的应用程序的口味,此功能也会忽略任何输入中的 (""),因为这些都是不需要的并且存在于我的输入中。

于 2015-05-06T15:51:11.033 回答
0

针对这种模式拆分:

(?<=\"?),(?!\")|(?<!\"),(?=\")

所以它将是:

String[] splitArray = subjectString.split("(?<=\"?),(?!\")|(?<!\"),(?=\")");

UPD:根据最近问题逻辑的变化,最好不要使用裸拆分,您应该先将逗号文本与非逗号文本分开,然后在最后一个上进行简单的split(“,”)。只需使用简单的 for 循环并检查您遇到了多少引号,同时将您读过的字符保存到 StringBuffer 中。首先,您将字符保存到 StringBuffer 中,直到遇到引号,然后将 StringBuffer 放入包含不在引号中的字符串的数组中。然后你创建新的 StringBuffer 并保存你读入的下一个字符,在你遇到第二个逗号之后,你已经停止并将新的 StringBuffer 放入包含逗号字符串的数组中。重复直到字符串结束。因此,您将有 2 个数组,一个带有逗号的字符串,其他字符串不是逗号。然后你应该拆分第二个数组的所有元素。

于 2011-05-11T18:38:20.497 回答
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它产生:

测试05
“测试,05”
测试”
测试05

并因为test05, "test 05", test", test 05它产生:

测试05
“测试 05”
测试”
测试05
于 2011-05-11T21:32:02.827 回答
0

除非你真的需要 DIY,否则你应该考虑 Apache Commons 类 org.apache.commons.csv.CSVParser

http://commons.apache.org/sandbox/csv/apidocs/org/apache/commons/csv/CSVParser.html

于 2011-05-11T20:06:19.790 回答