我想在每次出现alpha-beta字符时分割我的字符串。
例如:
"s1l1e13"到一个数组:["s1","l1","e13"]
当试图通过正则表达式使用这个简单的拆分时,我得到了一些奇怪的结果:
testStr ="s1l1e13"
Arrays.toString(testStr.split("(?=[a-z])"))
给了我一系列:
["","s1","l1","e13"]
如何在没有空数组元素的情况下创建拆分?
我尝试了更多的东西:
testStr ="s1"
Arrays.toString(testStr.split("(?=[a-z])"))
确实返回当前数组:["s1"]
但是在尝试使用子串时
testStr ="s1l1e13"
Arrays.toString(testStr.substring(1).split("(?=[a-z])")
我得到回报["1","l1","e13"]
我错过了什么?
我使用谷歌番石榴,它更具可读性,它有很多有用的类,方便。"(。)。Splitter.on omitEmptyStrings()分裂。(" how.are.you?");" 你会得到更易读的代码,不会乱用正则表达式。
您的前瞻标记a到z的任何字符之前的每个位置;标记以下位置:
s1 l1 e13
^ ^ ^
所以通过split仅使用Lookahead,它返回["","s1","l1","e13"]
你可以在这里使用负面观察。这看后面是看不到字符串的开头。
String s ="s1l1e13";
String[] parts = s.split("(?
System.out.println(Arrays.toString(parts)); //=> [s1, l1, e13]
很多工作答案,但你是最快的枪,工作! 谢谢!
@amitben谢谢
您的问题是(?=[a-z])表示"放在[a-z]之前"并在您的文本中
s1l1e13
你有3个这样的地方。我会用|标记它们
|s1|l1|e13
所以拆分(不幸的是正确)会产生"" "s1" "l1" "e13"并且不会自动删除第一个空元素。
要解决此问题,您至少有两个选择:
确保在您需要拆分的地方之前有某些东西(它不在您的字符串的开头)。如果要在数字之后但在字符之前分割,则可以使用例如(?<=\\d)(?=[a-z])
(PREFFERED SOLUTION)开始使用Java 8,如果在split上使用的正则表达式为零长度(环视为零长度),则会在结果数组的开头自动删除空字符串。
非常感谢@Pshemo的详细解答,这解释了很多!
@amitben欢迎你:)
所以你的匹配似乎是模式x ###,其中x是一个字母,而#是一个数字。
我做了以下正则表达式:
([a-z][0-9]+)
谢谢,但这个正则表达式给我留下了一个空数组..
问题是初始"s"算作字母字符。因此,正则表达式试图分裂为s。
问题是在s之前没有任何内容,因此正则表达式计算机决定通过添加null元素来显示没有任何内容。如果你以"s"(或任何其他字母)结束,它最终会做同样的事情。
如果这是你要拆分的唯一字符串,或者你所拥有的每个数组都以字母开头但不以一个字母结尾,则只需截断数组以省略第一个元素。否则,您可能需要在创建时循环遍历每个数组,以便可以删除空元素。
第一个匹配找到""是好的,因为它展望任何alpha字符,称为zero-width lookahead,所以它不需要实际匹配任何东西。所以开头的"s"是字母数字,并且它与可能的点匹配。
如果您希望正则表达式始终匹配某些内容,请使用".+(?=[a-z])"
谢谢,但这给我留下了[, e13]