【问题标题】:RegEx for matching special patterns用于匹配特殊模式的正则表达式
【发布时间】:2019-10-13 07:21:44
【问题描述】:

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

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

喜欢:

LQ*2+4 |长Q+4*2 |长Q*2 | LQ+8 |量产

描述也是可选的

我试过的是这样的:

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

【问题讨论】:

  • 您能否提供几个具体的示例字符串以及预期的输出应该是什么?很难理解你在问什么
  • @Misantorp 我编辑了它..
  • 为什么不在| 上拆分62.00|LQ+2*2,FP,MD*3 "Description"?这将为您提供62.00LQ+2*2,FP,MD*3 "Description",因此您已经拥有number 部分。然后将 one (first) 空间上的第二部分拆分为两部分(通过split(" ", 2) 得到LQ+2*2,FP,MD*3 "Description",这样即使描述有更多空格,它也会在一个字符串中。然后用逗号分隔LQ+2*2,FP,MD*3 以获取每个玩家。
  • @Pshemo 因为我不知道用户是否会在它的位置放一个数字或其他东西..
  • 我的印象是您的正则表达式仅用于将有效字符串 分隔 到稍后将通过命名组访问的部分。但是现在您提到您的字符串还可以包含其他不正确的数据。您能否将这些信息添加到您的问题中,可能带有示例?

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


【解决方案1】:

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

^(\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})?) - 匹配可以在小数点后有 2 位可选的数字并在 group1 中捕获它
  • \| - 匹配文字 | 出现在数字之后的输入中
  • ([a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?(?:,[a-zA-Z]{2}(?:(?:\+\d+(?:\*\d+)?)|(?:\*\d+(?:\+\d+)?))?)*) - 这部分匹配两个字母,后跟 + 后跟数字的任意组合,可选 * 后跟数字或 * 后跟数字,可选 + 后跟数字恰好一次或整个它是可选的,并在 group2 中捕获它
  • (?: +(.+))? - 这匹配可选描述并在 group3 中捕获它
  • $ - 标记输入结束

Regex Demo

【讨论】:

    【解决方案2】:

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


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

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

    【讨论】:

    • 我现在要对此进行测试,但我需要避免的是 LQ+2+2,因此用户中有两个相同的量词,如 LQ+2+4、LQ*2*7或两个以上的量词,如 LQ*2+3+7*8
    • 我会写我希望它匹配的案例,因为这样会更容易
    • 我更新了它,也谢谢你的帮助:) 我已经为此苦苦挣扎了一段时间regex101.com/r/IZXW7j/3
    • Pushpesh 解决了它。也谢谢你的帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多