【问题标题】:stop matching string in regex after my pattern在我的模式之后停止在正则表达式中匹配字符串
【发布时间】:2017-03-19 01:22:37
【问题描述】:

我正在尝试匹配一个字符串模式,而我的正则表达式是

/^[a-zA-Z0-9]*(-|\s)*Iphone 7(\s|-)?(\p{N}GB)?\B/i

我要匹配的字符串是Apple Iphone 7 Plus 16 Gb。我想匹配确切的正则表达式,即 Iphone 7 应该只与以下匹配

  • [任何数字或字符串] 苹果 iphone 7
  • [任何数字或字符串] 苹果 iphone 7 16 GB
  • [任何数字或字符串] 苹果 iphone 7 32GB - 银色
  • [任何数字或字符串] apple iphone 7 plus(不应匹配)
  • [任何数字或字符串] apple iphone 7s(不应匹配)

请让我知道我做错了什么? 这是正则表达式link

【问题讨论】:

  • 你为什么使用[a-zA-Z0-9]*(-|\s)*而不是apple iphone,因为你说“它应该只与关注者匹配”?
  • Apple Iphone 7 之前的所有功能都可以正常工作,因此只有最后一个不工作的部分
  • @SaggingRufus 是的,这就是问题所在。
  • apple iphone 7 plus(不应该匹配).....应该不匹配或者这不匹配.....清除这个混淆

标签: php regex


【解决方案1】:

不确定是否能很好地理解您的需求,但如何:

/^.*?iphone 7(?:\s+(?:plus\s+)?\d+\s?gb.*)?$/i

说明:

/               : regex delimiter
  ^             : begining of string
    .*?         : 0 or more any characters not greedy
    iphone 7    : literally
    (?:         : start non capture group
      \s+       : 1 or more spaces
      (?:       : start non capture group
        plus    : literally
        \s+     : 1 or more spaces
      )?        : end group^, optional
      \d+       : 1 or more digits
      \s?       : 1 optional space
      gb        : literally
      .*        : 0 or more any character
    )?          : end group, optional
  $             : end of string
/i              : regex delimiter, case insensitive

实际操作:

$tests = array(
'any digits or string apple iphone 7',
'any digits or string apple iphone 7 16 gb',
'any digits or string apple iphone 7 32GB - Silver',
'any digits or string apple iphone 7 plus',
'any digits or string apple iphone 7s',
);
foreach ($tests as $test) {
    echo "$test\t ==> ";
    if (preg_match('/^.*?iphone 7(?:\s+(?:plus\s+)?\d+\s?gb.*)?$/i', $test)) {
        echo "match\n";
    } else {
        echo "doesn't match\n";
    }
}

输出:

any digits or string apple iphone 7  ==> match
any digits or string apple iphone 7 16 gb    ==> match
any digits or string apple iphone 7 32GB - Silver    ==> match
any digits or string apple iphone 7 plus     ==> doesn't match
any digits or string apple iphone 7s     ==> doesn't match

【讨论】:

  • 谢谢你的解释,但 plus 只是一个占位符,可能有 iphone 6s 不应该与 iphone 6 匹配,但 iphone 6 应该与 iphone 16gb 匹配等等
【解决方案2】:

如果您真的只对字符串的 Apple Iphone 7 位感兴趣,并且您正在使用 PHP,为什么不干脆这样做:

if (stripos($string,'Apple Iphone 7 Plus') !== FALSE) echo 'Wow a 7 Plus!';
else if (stripos($string,'Apple Iphone 7') !== FALSE) echo 'It is only a 7';

换句话说:尽可能避免使用复杂的正则表达式,只在需要时使用它们。

【讨论】:

  • 我必须遵循问题中描述的模式,所以我不能简单地使用strpos
  • 它也将匹配 iphone 7 plus。
  • 是的,没错,但只需添加一行即可解决。
  • 您可以在解析用户代理字符串时使用 reg exp。我唯一的一点是 reg exp 应该只在其他选项失败时使用。你觉得他们很难,其他人也一样。它们会使您的代码不可读和不可预测。
【解决方案3】:

有了这个正则表达式,你可以匹配,如果你想也可以提取一些关于它的信息

(?!apple iphone .* plus)(?:apple iphone 7)(?>\s(?<storage>\d+)?\s?(?:gb))?

你可以看到demo

我已经更新了一点,现在将与以下匹配

  • [任何数字或字符串] 苹果 iphone 7
  • [任何数字或字符串] 苹果 iphone 7 16 gb
  • [任何数字或字符串] 苹果 iphone 7 32GB
  • [任何数字或字符串] 苹果 iphone 7 [任何数字或字符串]
  • [任何数字或字符串] 苹果 iphone 7 16 gb [任何数字或字符串]
  • [任何数字或字符串] Apple iphone 7 32GB [任何数字或字符串]

与以下不匹配

  • [任何数字或字符串] 苹果 iphone 7 plus
  • [任何数字或字符串] 苹果 iphone 7 plus [任何数字或字符串]
  • [任何数字或字符串] 苹果 iphone 7 16 gb plus
  • [任何数字或字符串] Apple iphone 7 16 gb plus [任何数字或字符串]
  • [任何数字或字符串] Apple iphone 7 32GB plus [任何数字或字符串]

【讨论】:

  • 这是匹配apple iphone 7gBBBBB GGG
  • @Toto 试试新版本
  • 这样更好,但它匹配apple iphone 77777GG。字符类中还有一个错字,你有2个b
  • @Toto 我认为现在它更强大了
猜你喜欢
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多