如何使用某些分隔符拆分String但不在Java中删除该分隔符?

sag*_*sag 67 java regex string split

我在分裂方面遇到了问题String.

我想String用一些分隔符拆分一个但不丢失该分隔符.

当我们somestring.split(String separator)在Java中使用方法时,它会拆分String但从中删除分隔符部分String.我不希望这种情况发生.

我想要如下结果:

String string1="Ram-sita-laxman";
String seperator="-";
string1.split(seperator);
Run Code Online (Sandbox Code Playgroud)

输出:

[Ram, sita, laxman]
Run Code Online (Sandbox Code Playgroud)

但我希望结果如下所示:

[Ram, -sita, -laxman]
Run Code Online (Sandbox Code Playgroud)

有没有办法获得这样的输出?

Ada*_*ter 206

string1.split("(?=-)");
Run Code Online (Sandbox Code Playgroud)

这工作,因为split其实需要一个正则表达式.你实际看到的是"零宽度正向前瞻".

我想解释更多,但我女儿想参加茶话会.:)

编辑:回来!

为了解释这一点,我将首先向您展示一个不同的split操作:

"Ram-sita-laxman".split("");
Run Code Online (Sandbox Code Playgroud)

这会将您的字符串拆分为每个零长度字符串.每个字符之间都有一个零长度字符串.因此,结果是:

["", "R", "a", "m", "-", "s", "i", "t", "a", "-", "l", "a", "x", "m", "a", "n"]
Run Code Online (Sandbox Code Playgroud)

现在,我修改我的正则表达式("")只匹配零长度字符串,如果它们后跟一个破折号.

"Ram-sita-laxman".split("(?=-)");
["Ram", "-sita", "-laxman"]
Run Code Online (Sandbox Code Playgroud)

在那个例子中,?=意思是"前瞻".更具体地说,它意味着" 积极的向前看".为什么"积极"?因为你也可以有负的 lookahead(?!),它会在每个零长度字符串上拆分,后面没有短划线:

"Ram-sita-laxman".split("(?!-)");
["", "R", "a", "m-", "s", "i", "t", "a-", "l", "a", "x", "m", "a", "n"]
Run Code Online (Sandbox Code Playgroud)

你也可以有正面的lookbehind(?<=),它会在每个零长度的字符串上分开,前面有一个破折号:

"Ram-sita-laxman".split("(?<=-)");
["Ram-", "sita-", "laxman"]
Run Code Online (Sandbox Code Playgroud)

最后,您还可以使用负lookbehind(?<!),它将在每个零长度字符串上分割,该字符串前面没有短划线:

"Ram-sita-laxman".split("(?<!-)");
["", "R", "a", "m", "-s", "i", "t", "a", "-l", "a", "x", "m", "a", "n"]
Run Code Online (Sandbox Code Playgroud)

这四个表达式统称为外观表达式.

奖金:把它们放在一起

我只是想展示我最近遇到的一个结合了两个环视表达式的例子.假设您希望将CapitalCase标识符拆分为其标记:

"MyAwesomeClass" => ["My", "Awesome", "Class"]
Run Code Online (Sandbox Code Playgroud)

您可以使用此正则表达式完成此操作:

"MyAwesomeClass".split("(?<=[a-z])(?=[A-Z])");
Run Code Online (Sandbox Code Playgroud)

这将分隔每个零长度字符串,前面是小写字母((?<=[a-z])),后跟大写字母((?=[A-Z])).

此技术也适用于camelCase标识符.

  • +1:哇,从来不知道正则表达式如此强大! (5认同)
  • 与您女儿的茶话会是解决世界面临的真正问题的美妙解决方案.我赞成这个答案. (3认同)
  • +1很优雅的解决方案 (2认同)
  • 你能否发表一个例子,说明如何在爆发之前和之后进行分裂?即.生产`ram, - ,sita, - ,laxman` (2认同)
  • 哪些浏览器支持这个?`"Ram-sita-laxman".split("(?<= - )");`导致一个字符串`["Ram-sita-laxman"]`. (2认同)

And*_*per 6

这有点狡猾,但您可以使用替换函数引入虚拟分隔符。我不知道 Java 方法,但在 C# 中它可能是这样的:

string1.Replace("-", "#-").Split("#");
Run Code Online (Sandbox Code Playgroud)

当然,您需要选择一个虚拟分隔符,保证它不会出现在字符串中的其他任何位置。


Dal*_*mas 2

一种方法是分割字符串,然后在每个提取的字符串的开头添加分隔符(第一个字符串除外)。