本文目录导读:

在 PHP 中,默认的正则匹配是贪婪匹配(尽可能多地匹配字符),要关闭贪婪匹配,可以使用以下几种方法:
使用非贪婪量词 (最常用)
在量词(、、)后面添加 ,使其变为非贪婪匹配。
$str = "<div>内容1</div><div>内容2</div>";
// 贪婪匹配(默认)
preg_match('/<div>(.*)<\/div>/', $str, $matches);
print_r($matches[1]); // 输出: 内容1</div><div>内容2
// 非贪婪匹配
preg_match('/<div>(.*?)<\/div>/', $str, $matches);
print_r($matches[1]); // 输出: 内容1
常用的非贪婪量词
// 贪婪的 * 改为非贪婪
*? // 匹配0次或多次,但尽可能少
// 贪婪的 + 改为非贪婪
+? // 匹配1次或多次,但尽可能少
// 贪婪的 ? 改为非贪婪
?? // 匹配0次或1次,但尽可能少
// 贪婪的 {n,m} 改为非贪婪
{n,m}? // 匹配n到m次,但尽可能少
完整示例
// 示例1:匹配HTML标签内容
$html = "<p>第一段</p><p>第二段</p>";
// 贪婪匹配
preg_match_all('/<p>(.*)<\/p>/', $html, $greedy);
print_r($greedy[1]);
// Array ( [0] => 第一段</p><p>第二段 )
// 非贪婪匹配
preg_match_all('/<p>(.*?)<\/p>/', $html, $nonGreedy);
print_r($nonGreedy[1]);
// Array ( [0] => 第一段 [1] => 第二段 )
// 示例2:匹配URL参数
$url = "?name=john&age=25&city=beijing";
// 贪婪匹配
preg_match('/name=(.*)&/', $url, $greedy);
echo $greedy[1]; // 输出: john&age=25&city
// 非贪婪匹配
preg_match('/name=(.*?)&/', $url, $nonGreedy);
echo $nonGreedy[1]; // 输出: john
使用 U 修饰符(全局非贪婪)
可以使用 U 修饰符让整个模式变为非贪婪模式, 的作用相反(变成贪婪)。
$str = "<div>内容1</div><div>内容2</div>";
// 使用 U 修饰符,全局非贪婪
preg_match('/<div>(.*)<\/div>/U', $str, $matches);
print_r($matches[1]); // 输出: 内容1
// 在 U 模式下,加 ? 反而变成贪婪
preg_match('/<div>(.*?)<\/div>/U', $str, $matches);
print_r($matches[1]); // 输出: 内容1</div><div>内容2
实践建议
- 推荐使用 方式:在需要非贪婪的位置显式添加 ,代码更清晰
- 谨慎使用
U修饰符:它会反转整个模式的贪婪行为,可能导致混淆
// 推荐写法 - 只在需要的地方使用非贪婪 $pattern = '/<a href="(.*?)".*?>(.*?)<\/a>/'; // 不推荐使用 U 修饰符(可能造成混淆) $pattern = '/<a href="(.*)".*>(.*)<\/a>/U';
| 方法 | 语法 | 说明 |
|---|---|---|
| 单个量词非贪婪 | {n,m}? |
最常用,局部控制 |
| 全局非贪婪 | 模式加 U 修饰符 |
全局控制,慎用 |
最佳实践:在需要非贪婪匹配的位置使用 后缀,而不是使用 U 修饰符,这样代码更易读和可维护。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播