Java - 如何拆分基于列的字符串?

3
我有一个文件中的以下两行:
16.1 14.3 8.8 7.0 7.85 13.29 18.75 13.08 13.10
6.7 5.4 6.39
我能够使用“\\ s+”正则表达式拆分第一行。但我无法拆分第二行。 我希望以这样的方式拆分上述字符串,以便我将获得以下输出:
row[1] = [16.1, 14.3, 8.8, 7.0, 7.85, 13.29, 18.75, 13.08, 13.10]
row[2] = [6.7, 5.4, null, null, 6.39, null, null, null, null]

以下是我需要解析的屏幕截图:

enter image description here


4
刚才的编辑可能不是一个好主意,因为它明显改变了输入内容的格式。现在它有了一定数量的空格,而之前没有。原帖作者能否确认一下你的条目之间的空格数量是否遵循某种定义? - Ben
1
也许进一步阐述一下,如果我们将第一行的“18.75”替换为“23132.3312”,那么文件会是什么样子呢?这是否可能? 简单来说:当没有定义文件的外观时,就没有解析它的方法。 - Ben
2
"\\\s+" is not a valid RegEx. It should be "\\s+" - Saif Ahmad
这似乎有效:https://regex101.com/r/OFWVUP/1 - jrtapsell
@saifahmad,没有数据是TAB间隔的。请查看@YCF_L的解决方案。那是正确的解决方案。 - Pranit More
显示剩余8条评论
4个回答

2

看起来你的输入在第一个数字开始到下一个开始数字之间有一个固定长度 (7):

16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10
^^^^^^^--------(7)

在这种情况下,您可以使用以下正则表达式将输入分割:(?<=\\G.{7})。请参考此链接了解更多信息:

String text1 = "16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10";
String text2 = "6.7    5.4                   6.39                             ";

String[] split1 = text1.split("(?<=\\G.{7})");
String[] split2 = text2.split("(?<=\\G.{7})");

输出

[16.1   , 14.3   ,  8.8   ,  7.0   ,  7.85  , 13.29  , 18.75  , 13.08  ,  13.10]
[6.7    , 5.4    ,        ,        ,  6.39  ,        ,        ,        ,       ]

更好的解决方案

如果你希望得到null而不是空值,可以使用以下代码:

List<String> result = Arrays.asList(text2.split("(?<=\\G.{7})"))
        .stream()
        .map(input -> input.matches("\\s*") ? null : input.trim())
        .collect(toList());

输出

[16.1, 14.3, 8.8, 7.0, 7.85, 13.29, 18.75, 13.08, 13.10]
[6.7, 5.4, null, null, 6.39, null, null, null, null]

你确定 OP 的 text2 末尾有空格吗? - revo
@revo,是的,它有尾随空格。 - Pranit More
@PranitMore,你需要在你的问题中提到这一点,请注意revo的评论是一个好观点。 - Youcef LAIDANI
谢谢YCF_L!这个解决方案可行。非常感谢!很抱歉是我的错误。我应该在之前提到尾随空格。你能解释一下这个正则表达式(?<=\\G.{7})吗? - Pranit More
4
这句话的意思是:“@PranitMore 这是一种将字符串按特定长度拆分的技巧。如果想了解更多,请查看这里的答案 https://dev59.com/4m865IYBdhLWcg3wi_M2#3761521”。 - Youcef LAIDANI

0
你可以使用流和拆分行,然后拆分单元格,得到一个列表的列表:
List<List<String>> matrix = Arrays.asList(text.split("\n"))
            .stream()
            .map(line -> Arrays.asList(line.split("\\s+")))
            .collect(Collectors.toList())

这将给你一个二维数组/列表的值。

当进行测试时:

String text = "16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10\n" + " 6.7    5.4                   6.39";

这将输出:

[[16.1, 14.3, 8.8, 7.0, 7.85, 13.29, 18.75, 13.08, 13.10], [, 6.7, 5.4, 6.39]]

这个解决方案不符合我的标准,因为我需要在解决方案中也有空列。 - Pranit More

0

使用Guava的Splitter.fixedLength(int)方法

String[] rows = {
    "16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10",
    "6.7    5.4                   6.39                             "
  };
Splitter splitter = Splitter.fixedLength(7);
for(String row: rows) {
  List<String> data = splitter.splitToList(row);
  for (int i = 0; i < data.size(); i++) {
    System.out.printf("Column %d: %s%n", i+1, data.get(i));
  }
}

-1

对我来说,这似乎是一个定宽文件。

请尝试以下正则表达式。

.{7}

您可以根据列宽在花括号内更改值,

.{column_width_goes_here}

Sample https://regex101.com/r/SZZxbB/1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接