如何通过换行符和固定数量的制表符拆分字符串,例如 Java 中的“\n\t”?

How to split a string by a newline and a fixed number of tabs like "\n\t" in Java?

我的输入字符串如下:

 String input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";

我的预期结果是

要求将输入拆分为“\n\t”而不是“\n\t\t”。

的简单尝试
String[] answers = input.split("\n\t");

也从最后一个条目中拆分“\tfile.ext”。有没有一个简单的正则表达式可以解决这个问题?谢谢!

您可以在换行符和制表符处拆分,并在其后的右侧断言不是制表符。

\n\t(?!\t)

看到一个regex demo

String input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
String[] answers = input.split("\n\t(?!\t)");
System.out.println(Arrays.toString(answers));

输出

[dir, subdir1, subdir2
        file.ext]

如果您正在寻找通用方法,这在很大程度上取决于输入通常具有的格式。如果您的格式对于所有可能的输入(dir\n\tdir2\n\tdir3\n\t\tfile.something)都是静态的,一种方法如下:

String input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
String[] answers = input.split("\n\t");

for (int i = 1; i < answers.length; i++)
    if (answers[i].contains("\t"))
        answers[i-1] = answers[i-1] + "\n\t" + answers[i];

String[] answersFinal = Arrays.copyOf(answers, answers.length-1);
for (int i = 0; i < answersFinal.length; i++)
    answersFinal[i] = answers[i];

for (String s : answersFinal)
    System.out.println(s);

但这不是一个好的解决方案,我建议重新格式化您的输入以包含可用于拆分输入的特殊字符序列,例如:

String input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
input = input.replaceAll("\n\t", "%%%").replaceAll("%%%\t", "\n\t\t");

然后用'%%%'分割输入,你会得到你想要的输出。

但是,这在很大程度上取决于您希望它的通用性,最好的解决方案是使用一种完全不同的方法来实现您想要的,但我无法提供它,因为我没有足够的信息你在开发什么。

你可以简单地做:

String input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
String[] modifiedInput = input.replaceAll("\n\t\t", "####").replaceAll("\n\t", "§§§§").replaceAll("####", "\n\t\t").split("§§§§");
  1. 替换每个包含 \n\t
  2. 的 \n\t\t
  3. 替换每个\n\t
  4. 改回 \n\t\t,因为您似乎想保留它
  5. 拆分。

效率不是很高,但如果您不在海量数据情况下使用它,仍然可以足够快地工作。

这种方法更有效,因为它只使用 2 次拆分,但只有在末尾只有一个前缀为 \n\t\t 的元素时才有效。访问一个数组是一种便宜的 O(1) 如此恒定的时间。更多代码但更少完整迭代(replaceAll、split)。

final String input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
final String[] s1 = input.split("\n\t\t");
final String last  = s1[s1.length - 1];
final String[] modifiedInput = s1[0].split("\n\t");
modifiedInput[modifiedInput.length -1] = modifiedInput[modifiedInput.length -1] + "\n\t\t" + last;