正则表达式:忽略组的顺序

Eye*_*ear 6 java regex

我有一段文字:

randomtext 1150,25 USD随机文本

和一个简单的正则表达式来提取不同货币的金额:

(((\d+)(,?\s?|.)(\d{1,2}))\s?(PLN|EUR|USD|CHF|GBP))

这给了我这些团体:

  1. 1150,25美元
  2. 1150,25
  3. 1150
  4. ,
  5. 25
  6. 美元

但是,数字和货币可能会交换其头寸:

randomtext USD 1150,25随机文字

要么

randomtext USD1150,25 randomtext

在保持当前分组的同时,如何在不重复整个组(AB | BA)的情况下提高我的正则表达式以满足该条件?

Cas*_*yte 5

您可以使用这种模式:

String p = "\\b (?=[\\dPEUCG])  # to jump quickly at interesting positions       \n" +
           "(?=     # open a lookahead                                           \n" +
           "    (?> [\\d,]+ \\s* )? # perhaps the value is before                \n" +
           "    (?<currency> PLN|EUR|USD|CHF|GBP )  # capture the currency       \n" +
           "    (?:\\b|\\d) # a word boundary or a digit                         \n" +
           ")       # close the lookahead                                        \n" +
           "(?> [B-HLNPRSU]{3} \\s* )? (?<value> \\d+(?:,\\d+)? )                  ";

Pattern RegComp = Pattern.compile(p, Pattern.COMMENTS);

String s = "USD 1150,25 randomtext \n" +
           "Non works randomtext 1150,25 USD randomtext\n" +
           "Works randomtextUSD 1150,25 USD randomtext\n" +
           "Works randomtext USD 1150,25 randomtext\n" +
           "Works randomtext USD1150,25 randomtext\n" +
           "Non work randomtext 1150,25 USD randomtext";

Matcher m = RegComp.matcher(s);

while( m.find() ) {
    System.out.println(m.group("value") + " : " + m.group("currency"));
}
Run Code Online (Sandbox Code Playgroud)

想法是在先行捕获货币(即零宽度断言)。前瞻仅是一个断言,并且不使用字符,并且内部子模式之前已经描述了一个最终值。因此,货币头寸不会发生任何变化。该值被捕获在超前区域之外。

关于\\b (?=[\\dPEUCG]):此子模式的目标是过滤字符串中不是以数字或不同货币的第一个字母之一开头的单词开头的位置,而不测试整个模式。

  • 在这一点上,出于理智的考虑,也许应该只使用多个正则表达式,或者完全不使用它们。 (3认同)