【问题标题】:Regex match specific string without other string正则表达式匹配特定字符串而没有其他字符串
【发布时间】:2021-03-05 07:09:05
【问题描述】:

所以我做了这个正则表达式:

/(?!for )€([0-9]{0,2}(,)?([0-9]{0,2})?)/

只匹配以下两个句子中的第一个:

  1. 这些商品可享受 50,20 欧元的折扣
  2. 此商品现价 30.20 欧元

您可能已经注意到,我希望不要匹配第二句中的金额,因为它不是折扣金额。但我很不确定如何在正则表达式中找到它,因为我能找到所有的报价选项,例如:

(?!foo|bar)

从我的示例中可以看出,此选项似乎不能解决我的问题。

示例: https://www.phpliveregex.com/p/y2D

建议?

【问题讨论】:

  • 你的问题到底是什么,我在regex101.com/r/uQmAH2/1 上看起来是正确的?
  • 您绝对应该重新表述您的问题,并包含有关您如何区分折扣和非折扣金额的信息(它们是否总是按特定顺序出现,是否总是伴随着某个短语...... )。
  • 更新了一个来自 php live regex 的例子:phpliveregex.com/p/y2D

标签: php regex match except


【解决方案1】:

你可以使用

(?<!\bfor\s)€(\d+(?:,\d+)?)

请参阅regex demo

详情

  • (?&lt;!\bfor\s) - 如果在当前位置之前有一个完整的单词 for 和一个空格,则匹配失败
  • - 一个欧元符号
  • (\d+(?:,\d+)?) - 第 1 组:一位或多位数字后跟可选的逗号序列和一位或多位数字

PHP demo

$strs= ["discount of €50,20 on these items","This item on sale now for €30,20"];
foreach ($strs as $s){
    if (preg_match('~(?<!\bfor\s)€(\d+(?:,\d+)?)~', $s, $m)) {
        echo $m[1].PHP_EOL;
    } else {
        echo "No match!";
    }
}

输出:

50,20
No match!

【讨论】:

    【解决方案2】:

    您可以确保匹配行中的第一个 discount

    \bdiscount\h[^\r\n€]*\K€\d{1,2}(?:,\d{1,2})?\b
    

    说明

    • \bdiscount\h一个词的边界,匹配折扣和至少一个空格
    • [^\r\n€]\K 匹配除 € 或换行符之外的任何字符 0+ 次,然后重置匹配缓冲区
    • €\d{1,2}(?:,\d{1,2})? 匹配 €,1-2 位数字,可选部分匹配 , 和 1-2 位数字
    • \b一个字边界

    Regex demo | Php demo

    $re = '/\bdiscount\h[^\r\n€]*\K€\d{1,2}(?:,\d{1,2})?\b/';
    $str = 'discount of €50,20 on these items €
    This item on sale now for €30,20';
    
    if (preg_match($re, $str, $matches)) {
        echo($matches[0]);
    }
    

    输出

    €50,20
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 2014-10-08
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多