正则表达式用于匹配特殊模式

时间:2019-05-27 18:17:42

标签: java regex regex-lookarounds regex-group regex-greedy

我正在尝试匹配这样的字符串:62.00|LQ+2*2,FP,MD*3 "Description" 如果十进制值为2位数(可选),则每个用户的特征是两个字符,其后可以跟着

  

(\ + [\ d] +)?或(\ * [\ d] +)?或没有,或两者都以不同的顺序

喜欢:

  

LQ * 2 + 4 | LQ + 4 * 2 | LQ * 2 | LQ + 8 | LQ

说明也是可选的

我尝试过的是这个

Pattern.compile("^(?<number>[\\d]+(\\.[\\d]{2})?)\\|(?<users>([A-Z]{2}){1}(((\\+[\\d]+)?(\\*[\\d]+)?)|((\\+[\\d]+)?(\\*[\\d]+)?))((,[A-Z]{2})(((\\+[\\d]+)?(\\*[\\d]+)?)|((\\+[\\d]+)?(\\*[\\d]+)?)))*)(\\s\\\"(?<message>.+)\\\")?$");

我需要获得所有用户,以便我可以用','分割用户,然后进一步将其正则表达式放入其中。但是我无法从中获取任何东西。

  

62.00 | LQ + 2 * 2,FP,MD * 3“说明”

应该是:

  

62.00

     

LQ + 2 * 2,FP,MD * 3

     

说明

可接受的输入应为以下类型:

  

62.00 | LQ + 2 * 2,FP,MD * 3

     

30 | LQ“汉堡”

     

35.15 | LQ * 2,FP + 2 * 4,MD * 3 + 4“土豆”

     

35.15 | LQ,FP,MD

2 个答案:

答案 0 :(得分:3)

此正则表达式应满足与您描述的输入相匹配的精确正则表达式,

^(\d+(?:\.\d{1,2})?)\|([a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?(?:,[a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?)*)(?: +(.+))?$

其中group1将包含最多可以有两位小数的可选小数,而group2将具有您在帖子中描述的逗号分隔的输入,而group3将包含可选的描述(如果存在)。

正则表达式的解释:

  • ^-字符串的开头
  • (\d+(?:\.\d{1,2})?)-匹配小数点后可以有可选两位数字的数字并将其捕获到组1中
  • \|-匹配数字后输入中出现的文字|
  • ([a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?(?:,[a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?)*)-该部分匹配两个字母,后跟+的任意组合,后跟数字,并可选地包含*,后跟数字,或*,后跟数字,并可选地具有+,后面紧跟着一个数字或全部是可选数字,并将其捕获到组2中。
  • (?: +(.+))?-这与可选描述相匹配,并将其捕获到group3中
  • $-标记输入结束

{{3}}

答案 1 :(得分:1)

我猜这里我们有几个可选的组,这可能不是问题。我遇到的问题是我不太确定输入的范围是多少以及期望的输出是什么。


RegEx 1

如果我们只是匹配所有内容,我想,我们可能会从类似以下内容开始:

[0-9]+(\.[0-9]{2})?\|[A-Z]{2}[+*]?([0-9]+)?[+*]?([0-9]+)?,[A-Z]{2},[A-Z]{2}[+*]?([0-9]+)?(\s+"Description")?

在这里,我们只需要在每个希望使其可选的子表达式后面添加一个?,然后使用字符列表和量词,并开始从左向右滑动所有内容,以覆盖所有输入。

如果我们想捕获,则只需将捕获的任何部分包裹在捕获组()中。

Demo

测试

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "[0-9]+(\\.[0-9]{2})?\\|[A-Z]{2}[+*]?([0-9]+)?[+*]?([0-9]+)?,[A-Z]{2},[A-Z]{2}[+*]?([0-9]+)?(\\s+\"Description\")?";
final String string = "62.00|LQ+2*2,FP,MD*3 \"Description\"\n"
     + "62|LQ+2*2,FP,MD*3 \"Description\"\n"
     + "62|LQ+2*2,FP,MD*3\n"
     + "62|LQ*2,FP,MD*3\n"
     + "62|LQ+8,FP,MD*3\n"
     + "62|LQ,FP,MD";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println("Full match: " + matcher.group(0));
    for (int i = 1; i <= matcher.groupCount(); i++) {
        System.out.println("Group " + i + ": " + matcher.group(i));
    }
}

RegEx 2

如果我们希望输出列出的三个组:

([0-9]+(\.[0-9]{2})?)\|([A-Z]{2}[+*]?([0-9]+)?[+*]?([0-9]+)?,[A-Z]{2},[A-Z]{2}[+*]?([0-9]+)?)(\s+"Description")?

Demo 2

测试

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "([0-9]+(\\.[0-9]{2})?)\\|([A-Z]{2}[+*]?([0-9]+)?[+*]?([0-9]+)?,[A-Z]{2},[A-Z]{2}[+*]?([0-9]+)?)(\\s+\"Description\")?";
final String string = "62.00|LQ+2*2,FP,MD*3 \"Description\"\n"
     + "62|LQ+2*2,FP,MD*3 \"Description\"\n"
     + "62|LQ+2*2,FP,MD*3\n"
     + "62|LQ*2,FP,MD*3\n"
     + "62|LQ+8,FP,MD*3\n"
     + "62|LQ,FP,MD";
final String subst = "\\1\\n\\3\\n\\7";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

// The substituted value will be contained in the result variable
final String result = matcher.replaceAll(subst);

System.out.println("Substitution result: " + result);

RegEx 3

基于更新后的所需输出,这可能会起作用:

([0-9]+(\.[0-9]{2})?)\|((?:[A-Z]{2}[+*]?([0-9]+)?[+*]?([0-9]+)?,?)(?:[A-Z]{2}[+*]?([0-9]+)?[*+]?([0-9]+)?,?[A-Z]{2}?[*+]?([0-9]+)?[+*]?([0-9]+)?)?)(\s+"(.+?)")?

DEMO