【问题标题】:php non-greedy regex problemphp非贪婪正则表达式问题
【发布时间】:2009-05-14 13:01:04
【问题描述】:

演示:

$str = 'bcs >Hello >If see below!';
$repstr = preg_replace('/>[A-Z0-9].*?see below[^,\.<]*/','',$str);
echo $repstr;

我希望这个小程序输出的是“bcs >Hello”,但实际上它只是“bcs”

我的模式有什么问题?

【问题讨论】:

  • 鉴于您的代码 sn-p,您的问题没有意义。你的陈述什么都没有替换模式。您的回答表明您想用某些东西替换它。
  • 程序按照您的要求执行。不清楚你想得到什么。再举一个例子。
  • 这与非贪婪的正则表达式有关,我认为它很清楚,为什么不呢?

标签: php regex non-greedy


【解决方案1】:

我认为问题在于您误解了非贪婪量词的行为方式。是的,一旦它开始运行,它就会比其他情况更早停止。但它不知道它之前的内容(或者可能是之后的文本)。它只关心它的当前位置。因此,您发布的正则表达式将匹配所有:

">Hello >If see below!"

让我们看看它是如何工作的:

/>[A-Z0-9].*?see below[^,\.<]*/

正则表达式首先在“bcs >Hello >If see below!”中查找“>”,然后找到第一个,即“Hello”之前的那个。好的,让我们检查表达式的下一部分:

[A-Z0-9]

下一个字符是 H,匹配模式 [A-Z0-9]。还好!下一个:

.*?

现在我们匹配所有非换行符,直到我们到达第一个实例以匹配“见下文[^,. 并不意味着您的整个模式将返回最小可能的匹配 字符串中所有可能的匹配项。它只是规定了特定字符匹配的功能。

您可能想尝试以下模式:

/>[A-Z0-9][^>]*?see below[^,\.<]*/

希望这能解决问题!

【讨论】:

  • 感谢您的回复,但这对我不起作用。因为在这种情况下它不起作用: $str = 'bcs Hello If
    见下文!';我想在处理后有'bcs Hello
  • 你可能会尝试详细阐述你的问题的上下文,你可能会得到一些更好的答案。
  • 解决方案如下: $str = 'bcs Hello If

    见下文!'; $repstr = preg_replace('/>[A-Z0-9][^>]*(>[^A-Z0-9]*)*见下文[^,\.
【解决方案2】:

你为什么不这样写:

$str = 'bcs >Hello >If see below!';
$repstr = preg_replace('/>If see below[^,\.<]*/','',$str);
echo $repstr;

【讨论】:

  • 因为我想要的是>之后的第一个大写字符或数字
【解决方案3】:

这可能是您现有的一个不错的选择。 您的正则表达式的问题在于,您没有选择您想要的内容,而是选择了您不想要的内容并将其替换为空字符串。 在我看来,最好的方法是选择你想要的,这就是下面的代码所做的。你最终得到的是第一个子模式匹配的内容,否则你会得到你的字符串。

$str = 'bcs >Hello >If see below!';
$repstr = preg_replace('/^([\w]+ >[\w]+).*?see below.*?$/i', '$1', $str);
var_dump($repstr);

我希望这会有所帮助。

【讨论】:

  • 对不起,我想要做的是完全替换:从“>之后的第一个大写字符或数字”开始,以“见下文[^,\.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 2010-10-20
  • 2013-02-15
  • 1970-01-01
相关资源
最近更新 更多