有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java正则表达式否定整个正则表达式

我想用正则表达式将此字符串解析为组:

{4: :35B:ISIN DE000XXXXXXX DISC.Z 11.11.11 XXXX90 1234 (HSBC T R.? B.) /F:12345/R:N/W:N/C:N/S:N/G:N/A:N/F:N /XX/Any Word :16S:CONFDET :16R:SETDET :22F::SETR//TRAD :11A::FXIB//EUR :16R:AMT :19A::DEAL//EUR222, :16S:AMT :16R:AMT :19A::LOCO//EUR555 :16S:AMT :16R:AMT :19A::OTHR//EUR444 :16S:AMT :16R:AMT :19A::SETT//EUR333,33 :16S:AMT :16S:SETDET -}

我创建了这个正则表达式(:\d\d[a-zA-Z]:*(\w*\/\/)?|:\d\d:)([^:]+) 它在大多数情况下都匹配,但在本例中不匹配。 我想提取如下组:

:35B: => ISIN DE000XXXXXXX DISC.Z 11.11.11 XXXX90 1234 (XXXX T R.? B.) /F:12345/R:N/W:N/C:N/S:N/G:N/A:N/F:N /XX/Any Word

:16S: => CONFDET

:16R: => SETDET

我原以为第二组中没有“:”。也许有人能帮我。我需要在下一个:\d\d\w:Block之前退出整个Sting

编辑:输入字符串具有键值结构。例如:35B:是键,下一个键之前的所有内容都是值(在本例中,值为'ISIN DE000XXXXXXX DISC.Z 11.11.11 XXXX90 1234(XXXX T R.?B.)/F:12345/R:N/W:N/C:N/S:N/G:N/A:N/F:N/XX/任何单词')。 我想提取输入字符串的键值对。下面是我想要的一个小代码示例:

CharSequence swiftMessage = "{4: :35B:ISIN DE000XXXXXXX DISC.Z 11.11.11 XXXX90 1234 (HSBC T R.? B.) /F:12345/R:N/W:N/C:N/S:N/G:N/A:N/F:N /XX/Any Word :16S:CONFDET :16R:SETDET :22F::SETR//TRAD :11A::FXIB//EUR :16R:AMT :19A::DEAL//EUR222, :16S:AMT :16R:AMT :19A::LOCO//EUR555 :16S:AMT :16R:AMT :19A::OTHR//EUR444 :16S:AMT :16R:AMT :19A::SETT//EUR333,33 :16S:AMT :16S:SETDET -}";

Pattern pattern = Pattern.compile("(:\\d\\d([a-zA-Z]):*(\\w*//)?|:\\d\\d:)([^:]+)");
Matcher matcher = pattern.matcher(swiftMessage);

while( matcher.find() ) {
    String key = matcher.group(1);
    String value = matcher.group(4);

    System.out.println(key + "=>" + value);

}

预期输出(结构为key=>;value):

:35B:=>ISIN DE000XXXXXXX DISC.Z 11.11.11 XXXX90 1234 (HSBC T R.? B.) /F:12345/R:N/W:N/C:N/S:N/G:N/A:N/F:N /XX/Any Word
:16S:=>CONFDET 
:16R:=>SETDET 
:22F::SETR//=>TRAD 
:11A::FXIB//=>EUR 
:16R:=>AMT 
:19A::DEAL//=>EUR222, 
:16S:=>AMT 
:16R:=>AMT 
:19A::LOCO//=>EUR555 
:16S:=>AMT 
:16R:=>AMT 
:19A::OTHR//=>EUR444 
:16S:=>AMT 
:16R:=>AMT 
:19A::SETT//=>EUR333,33 
:16S:=>AMT 
:16S:=>SETDET -}

在我的正则表达式中,键35B的值是'ISIN DE000XXXXXXX DISC'。Z 11.11.11 xx90 1234(HSBC T R.?B.)/F'因为我的正则表达式查找下一个冒号。expexted值应为“ISIN DE000XXXXXXX光盘”。Z 11.11.11 XXXX90 1234(汇丰银行T.R.?B.)/F:12345/R:N/W:N/C:N/S:N/G:N/A:N/F:N/XX/任何单词'

希望现在能更好地理解


共 (1) 个答案

  1. # 1 楼答案

    看起来您希望找到以(space):分隔的标记,然后将每个标记中第一个:之前的部分视为键,其余部分视为值

    那样的话,你可以试试

    (?<key>(?<=\\s):\\d\\d[a-zA-Z]):(?<value>.*?)(?=\\s:|$)
    

    这将试图

    • 找到前面有空格(?<=\\s):\\d\\d[a-zA-Z]部分,并将其放入名为key的组中
    • 找到最小的字符集(因为*?量词是不情愿的),直到找到下一个\\s:或字符串的结尾,并将这部分放在名为value的组中

    所以你的代码看起来像

    Pattern pattern = Pattern.compile("(?<key>(?<=\\s):\\d\\d[a-zA-Z]):(?<value>.*?)(?=\\s:|$)");
    Matcher matcher = pattern.matcher(swiftMessage);
    while( matcher.find() ) {
        String key = matcher.group("key");
        String value = matcher.group("value");
    
        System.out.println(key + "=>" + value);
    
    }
    

    另一种方法可以是简单地在\\s:上进行拆分,以获得以下部分的数据:

    {4:
    35B:ISIN DE000XXXXXXX DISC.Z 11.11.11 XXXX90 1234 (HSBC T R.? B.) /F:12345/R:N/W:N/C:N/S:N/G:N/A:N/F:N /XX/Any Word
    16S:CONFDET
    ...
    16S:SETDET -}
    

    然后在:上再次拆分每个部分,但拆分次数有限(因此"foo:bar:baz:".split(":",2)变成["foo", "bar:baz"]

    使用这种方法,您的代码可以看起来像

    for (String token : swiftMessage.toString().split("\\s:")){
        //System.out.println(token);
        //lets ignore first `{4:` part
        //maybe like this
        if (token.length()<=3) continue;
    
        String[] key_value = token.split(":",2);
        System.out.println(":"+key_value[0]+"=>"+key_value[1]);
    }