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

RegEx for matching special patterns

我正在尝试匹配这样的字符串:62.00|LQ+2*2,FP,MD*3 "Description" 其中小数位数为2位可选,每个用户用两个字符来表征,后面可以跟

(\+[\d]+)? or (\*[\d]+)? or none, or both, or both in different order

喜欢:

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>.+)\\")?$");

我需要获取所有用户,这样我就可以用“,”将它们分开,然后进一步正则表达式进入 it.But 我无法从 it.The 所需的输出中获取任何内容

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

应该是:

62.00

LQ+2*2,FP,MD*3

Description

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

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

30|LQ "Burgers"

35.15|LQ*2,FP+2*4,MD*3+4 "Potatoes"

35.15|LQ,FP,MD

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


正则表达式 1

如果我们只是匹配所有内容,我猜,我们可能希望从类似于以下内容的内容开始:

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

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

如果我们喜欢捕捉,那么我们只需用捕捉组包裹我们想要捕捉的任何部分()

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));
    }
}

正则表达式 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);

正则表达式 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

与您描述的输入相匹配的精确正则表达式应该由这个正则表达式实现,

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

其中 group1 将包含可以有最多两位数的可选小数的数字,group2 将按照您在 post 中的描述使用逗号分隔的输入,group3 将包含可选描述(如果存在)。

正则表达式解释:

  • ^ - 字符串开始
  • (\d+(?:\.\d{1,2})?) - 匹配小数点后可以有可选2位的数字并在group1
  • 中捕获它
  • \| - 匹配输入中数字
  • 后的文字 |
  • ([a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?(?:,[a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?)*) - 这部分匹配两个字母后跟 + 后跟数字的任意组合,并且可以选择 * 后跟数字或 * 后跟数字和可选地 + 后跟数字,可以是一次或整个数字是可选的,并将其捕获在 group2
  • (?: +(.+))? - 这与可选描述匹配并将其捕获在 group3
  • $ - 标记输入结束

Regex Demo