【问题标题】:Regarding Java String Manipulation关于Java字符串操作
【发布时间】:2010-02-11 02:48:59
【问题描述】:

在 split 命令之后,我将字符串 "MO""RET" 存储在 items[1] 数组中。在它被存储之后,我在这个字符串上做了一个替换,它替换了所有的双引号。 但我希望它存储为MO"RET。我该怎么做。在我使用拆分命令处理的csv文件中,重复文本字段内容中的双引号(例如:此帐户是""large"" one")。所以我想在中间保留两个引号之一如果它被重复,则字符串,如果存在则忽略结束引号。我该怎么做?

String items[] = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
items[1] has "MO""RET"
String recordType = items[1].replaceAll("\"","");

在这个记录类型有MORET之后,我希望它有MO"RET

【问题讨论】:

  • 不到一小时前,您发布了一个非常相似的问题stackoverflow.com/questions/2241758/…,您没有回复、否决、否决或接受该问题。如果你不回馈网站,人们就会停止给予你。
  • @Mark Byers:哦,我多么希望那是真的。

标签: java string replaceall


【解决方案1】:

不要使用正则表达式来拆分 CSV 行。这是自找麻烦;)只需逐个字符解析即可。这是一个例子:

public static List<List<String>> parseCsv(InputStream input, char separator) throws IOException {
    BufferedReader reader = null;
    List<List<String>> csv = new ArrayList<List<String>>();
    try {
        reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
        for (String record; (record = reader.readLine()) != null;) {
            boolean quoted = false;
            StringBuilder fieldBuilder = new StringBuilder();
            List<String> fields = new ArrayList<String>();
            for (int i = 0; i < record.length(); i++) {
                char c = record.charAt(i);
                fieldBuilder.append(c);
                if (c == '"') {
                    quoted = !quoted;
                }
                if ((!quoted && c == separator) || i + 1 == record.length()) {
                    fields.add(fieldBuilder.toString().replaceAll(separator + "$", "")
                        .replaceAll("^\"|\"$", "").replace("\"\"", "\"").trim());
                    fieldBuilder = new StringBuilder();
                }
                if (c == separator && i + 1 == record.length()) {
                    fields.add("");
                }
            }
            csv.add(fields);
        }
    } finally {
        if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
    }
    return csv;
}

是的,涉及的正则表达式很少,但它只会修剪单个字段的结尾分隔符和周围的引号。

但是,您也可以获取任何第 3 方Java CSV API

【讨论】:

  • 非常感谢。非常感谢。如果我的字符串的值为“TEST”REPLA”。如果字符串中间只有一个双引号,我如何删除第一个、最后一个引号并保留所有中间引号。我想要输出作为 TEST"REPLA 示例 2:"EXAM"PLE"2IN" 我希望输出为 EXAM"PLE"2IN 需要删除第一个和最后一个引号
  • 发布的代码示例已经这样做了(假设您的 CSV 文件遵循此处列出的 RFC4180 rfc-editor.org/rfc/rfc4180.txt)。
  • 我使用了你的代码。伟大的!嗯……有点小问题。我希望从电子表格导出文件的A,B,, 行中获得["A","B","",""],但我得到了["A","B",""]
  • @Paul:哦,我忽略了那个边缘情况。我更新了答案。
【解决方案2】:

怎么样:

String recordType = items[1].replaceAll( "\"\"", "\"" );

【讨论】:

  • 非常感谢。如果我的字符串的值为“TEST”REPLA”。如果字符串中间只有一个双引号,我如何删除第一个、最后一个引号并保留所有中间引号。我想要输出作为 TEST"REPLA 示例 2:"EXAM"PLE"2IN" 我希望输出为 EXAM"PLE"2IN 需要删除第一个和最后一个引号
  • 用正则表达式很难做到这一点,并涵盖有一个起始引号和没有结束引号等的情况。正则表达式开始变得非常复杂。你真的开始更好地解析整行了。如果您真的只想要特定的开始/结束引用案例,那么只需使用 charAt() 检查并执行子字符串。无论如何,它会比正则表达式更快。
【解决方案3】:

我更喜欢你使用replace 而不是replaceAll。 replaceAll 使用 REGEX 作为第一个参数。

要求是用一个 QUOTE 替换两个连续的 QUOTES

String recordType = items[1].replace( "\"\"", "\"" );

要查看 replace 和 replaceAll 之间的区别,请执行以下代码

recordType = items[1].replace( "$$", "$" );
recordType = items[1].replaceAll( "$$", "$" );

【讨论】:

  • 非常感谢。如果我的字符串的值为“TEST”REPLA”。如果字符串中间只有一个双引号,我如何删除第一个、最后一个引号并保留所有中间引号。我想要输出作为 TEST"REPLA 示例 2:"EXAM"PLE"2IN" 我希望输出为 EXAM"PLE"2IN 需要删除第一个和最后一个引号
【解决方案4】:

这里可以使用正则表达式。

recordType = items[1].replaceAll( "\\B\"", "" ); 
recordType = recordType.replaceAll( "\"\\B", "" ); 

第一个语句用空字符替换单词开头的引号。 第二个语句用空字符替换单词末尾的引号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2014-03-21
    • 2021-12-19
    • 2012-09-27
    • 2021-07-17
    • 1970-01-01
    相关资源
    最近更新 更多