【问题标题】:Regular Expression negate whole regex正则表达式否定整个正则表达式
【发布时间】:2015-03-17 08:52:47
【问题描述】:

我想用正则表达式将这个字符串解析成组:

{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

...

我预计第二组中没有“:”。也许有人可以帮助我。我需要提取整个 Sting 直到下一个 :\d\d\w: Block.

编辑:输入字符串具有键值结构。例如 :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 XXXX90 1234 (HSBC T R.? B.) /F',因为我的正则表达式会查找下一个冒号。 expexted 值应为 '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/任意字'

希望现在理解起来会更好。

【问题讨论】:

  • 请解释您尝试提取的输入的结构。这个正则表达式很难理解,而且输入很长:让Stack Overflow 轻松回答。

标签: java regex regex-negation


【解决方案1】:

您似乎想查找以(space): 分隔的标记,然后将每个标记中第一个: 之前的部分视为键,将其余部分视为值。

这种情况你可以试试

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

这会尝试

  • 找到:\\d\\d[a-zA-Z]前面有空格(?&lt;=\\s)的部分,并将其放入名为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 -}

然后再次拆分: 上的每个部分,但拆分数量有限,拆分为2(因此"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]);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多