在一个字符之间分割字符串

3

我想根据分隔符拆分字符串。 示例字符串:

String str="ABCD/12346567899887455422DEFG/15479897445698742322141PQRS/141455798951";

现在我希望字符串的格式为ABCD/12346567899887455422, DEFG/15479897445698742322141,即:

  • /之前仅有4个字符
  • /之后可以是任意数量的数字或字母。更新:只有在显示分隔符后,我才需要前4个字符,因为该字符串可能包含字母或数字。

我的代码尝试:

public class StringReq {

    public static void main(String[] args) {
        String str = "BONL/1234567890123456789CORT/123456789012345678901234567890HOLD/123456789012345678901234567890INTC/123456789012345678901234567890OTHR/123456789012345678901234567890PHOB/123456789012345678901234567890PHON/123456789012345678901234567890REPA/123456789012345678901234567890SDVA/123456789012345678901234567890TELI/123456789012345678901234567890";
        testSplitStrings(str);


    }

    public static void testSplitStrings(String path) {
        System.out.println("splitting of sprint starts \n");
        String[] codeDesc = path.split("/");
        String[] codeVal = new String[codeDesc.length];
        for (int i = 0; i < codeDesc.length; i++) {
            codeVal[i] = codeDesc[i].substring(codeDesc[i].length() - 4,
                    codeDesc[i].length());

            System.out.println("line" + i + "==> " + codeDesc[i] + "\n");
        }

        for (int i = 0; i < codeVal.length - 1; i++) {
            System.out.println(codeVal[i]);
        }
        System.out.println("splitting of sprint ends");
    }

}

看起来你想要进行正则表达式匹配,而不是分割。 - Joeri Hendrickx
4个回答

10

据您所述,/后面可能出现数字和字母,但在您的示例中,我没有看到任何应该包含在/之后结果中的字母。

因此,基于这个假设,您可以简单地在具有数字前缀和A-Z字符后缀的位置上进行分割。

为此,您可以使用具有正向环视机制的正则表达式进行split,例如str.split("(?<=[0-9])(?=[A-Z])")

演示:

String str = "BONL/1234567890123456789CORT/123456789012345678901234567890HOLD/123456789012345678901234567890INTC/123456789012345678901234567890OTHR/123456789012345678901234567890PHOB/123456789012345678901234567890PHON/123456789012345678901234567890REPA/123456789012345678901234567890SDVA/123456789012345678901234567890TELI/123456789012345678901234567890";
for (String s : str.split("(?<=[0-9])(?=[A-Z])"))
    System.out.println(s);

输出:

BONL/1234567890123456789
CORT/123456789012345678901234567890
HOLD/123456789012345678901234567890
INTC/123456789012345678901234567890
OTHR/123456789012345678901234567890
PHOB/123456789012345678901234567890
PHON/123456789012345678901234567890
REPA/123456789012345678901234567890
SDVA/123456789012345678901234567890
TELI/123456789012345678901234567890
如果你的字母实际上可以出现在第二部分(在/之后),那么您可以使用split函数,该函数将尝试查找具有四个字母字符和/之后的位置,例如 split("(?=[A-Z]{4}/)") (假设您至少使用Java 8,如果不是,则需要通过在正则表达式开头添加(?!^)(?<=.)来手动排除在字符串开头拆分的情况)。

TEST/123ABCDATA/123 这样的输入怎么处理?从问题中可以看出,应该是有效的,并且结果应该是 TEST/123ABCDATA/123 - Roger Gustavsson
我也在想这种情况,因为OP声称“在/任意数量的字符之后,甚至是数字和字母”,但看起来OP实际上只在第二部分使用数字,所以我基于字母实际上不会出现在第二部分的假设来回答。我会更新我的答案以反映这一点。 - Pshemo
我同意示例数据没有反映这一事实,但规范确实如此。以下正则表达式应该是正确的:(?<=.)(?=[A-Z]{4}/) - Roger Gustavsson
@RogerGustavsson 是的,我已经在我的答案中添加了非常相似的解决方案。顺便说一下,自从Java 8以来,我们不需要担心(?<=.)部分,因为对于零长度正则表达式(如环视)的split将不会在字符串开头产生空字符串,如果定界符在字符串开头找到。您可以在我发布的这里的问题中找到更多信息:https://dev59.com/kWEh5IYBdhLWcg3wMAwt - Pshemo

3

你可以使用正则表达式

    Pattern pattern = Pattern.compile("[A-Z]{4}/[0-9]*");
    Matcher matcher = pattern.matcher(str);
    while (matcher.find()) {
      System.out.println(matcher.group());
    }

2

改为:

String[] codeDesc = path.split("/");

只需使用此正则表达式(在 / 前的4个字符和之后的任何字符):

String[] codeDesc = path.split("(?=.{4}/)(?<=.)");

1
更简单的方法是使用 \d:

path.split("(?=[A-Za-z])(?<=\\d)");

编辑:

只包括4个任意大小字母的条件。

path.split("(?=[A-Za-z]{4})(?<=\\d)");

output:

BONL/1234567890123456789
CORT/123456789012345678901234567890
HOLD/123456789012345678901234567890
INTC/123456789012345678901234567890
OTHR/123456789012345678901234567890
PHOB/123456789012345678901234567890
PHON/123456789012345678901234567890
REPA/123456789012345678901234567890
SDVA/123456789012345678901234567890
TELI/123456789012345678901234567890

这是否是作者期望的结果仍不清楚。

数字字符可以与字母字符混合使用。有效的输入序列为:TEST/123ABCTEST/123CDE。应该是 TEST/123ABCTEST/123CDE。因此,你的答案不起作用。 - Roger Gustavsson
Roger Gustavsson,好的,你说得对,关于字符数量作者在帖子中提到过,但仍不清楚期望的结果和行为是什么。我为此解决方案添加了4个字母的条件以及小写字母的条件 - 我们不应该限制它们。你没有充分的理由来踩我的答案。你为什么要这样做呢?这是另一个评分最高的答案的版本。另一件事是你的解决方案也是错误的。你没有考虑到建议中的小写字母,因此根据这个政策它也应该被踩。 - Navidot
抱歉给你点了个踩。我太匆忙了,直到你编辑了回答后才能撤销它。 - Roger Gustavsson

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