PHP preg_replace问题

3
这是对我之前在这里发表的问题的跟进(感谢mario)。
好的,所以我有一个preg_replace语句,用于将一个url字符串替换为sometext,插入来自查询字符串的值(使用$_GET["size"]),并插入来自关联数组的值(使用$fruitArray["$1"]回溯引用)。
输入的url字符串应该是:
http://mysite.com/script.php?fruit=apple

输出字符串应该是:
http://mysite.com/small/sometext/green/

我手头的PHP代码如下:

$result = preg_replace('|http://www.mysite.com/script.php\?fruit=([a-zA-Z0-9_-]*)|e', ' "http://www.mysite.com/" .$_GET["size"]. "/sometext/" .$fruitArray["$1"]. "/"', $result);

这段代码输出以下字符串:
 http://mysite.com/small/sometext//

代码似乎跳过了$fruitArray["$1"]的值。我错过了什么吗?谢谢!

1
当询问这样的问题时,您应该完全删除 $_GET 和 $fruitArray,并使用常量来将问题局限于 preg_replace。也许您的变量是空的,我们无法确定。 - Riccardo Galli
@Riccardo Galli,你说得很对,我已经吸取教训了——不能再在烟盒背面写PHP代码了,必须使用PHP IDE——你有什么推荐的吗?我是个新手 :/ 谢谢。 - Matt
通过重写一些前面的代码,我成功解决了这个问题;我之前有其他的 preg_replace 调用干扰了 URL 字符串 :/ 也许我的上面的代码还算半好吧 :-) 这个项目开始很小,但现在已经有数百行代码了 - 对此我深表歉意 - 不过我真的很感谢大家的回答,谢谢! - Matt
4个回答

1

嗯,奇怪的事情。

你的代码在我这里完全正常(请参见下面我用于本地测试的代码)。

但是,我已经修复了你的正则表达式中的两个问题:

  1. 不要使用 | 作为分隔符,它在正则表达式中有意义。
  2. 你的正则表达式只是给出了它可以工作的假象,因为你没有转义 .。实际上,它也会匹配 http://www#mysite%com/script*php?fruit=apple

测试脚本:

$fruitArray = array('apple' => 'green');
$_GET = array('size' => 'small');
$result = 'http://www.mysite.com/script.php?fruit=apple';
$result = preg_replace('@http://www\.mysite\.com/script\.php\?fruit=([a-zA-Z0-9_-]*)@e', ' "http://www.mysite.com/" .$_GET["size"]. "/sometext/" .$fruitArray["$1"]. "/"', $result);
echo $result;

输出:

Rudis-Mac-Pro:~ rudi$ php tmp.php
http://www.mysite.com/small/sometext/green/

这让我想到的唯一可能是,$fruitArray 对你来说没有正确设置。
顺便说一下,我认为这可能更合适,因为它将为您提供更多的灵活性,更好的语法高亮,并且比使用e修饰符来内部调用PHP的evil()函数更有意义;-) 在我看来,这也更加清晰易读。
$result = preg_replace_callback('@http://www\.mysite\.com/script\.php\?fruit=([a-zA-Z0-9_-]*)@', function($matches) {
        global $fruitArray;
        return 'http://www.mysite.com/' . $_GET['size'] . '/sometext/' . $fruitArray[$matches[1]] . '/';
}, $result);

感谢您详细的解答和指出更好的方法; 我很感激。我要开始尝试 preg_replace_callback,这对我来说是新事物,谢谢 :) - Matt
没问题!很高兴能帮忙,也很欣慰听到你没有发布这段代码,因为它让我感到困惑,它可以在我的电脑上运行而在你的电脑上却不能;-) - Rudi Visser

1

我再写一遍,我不很清楚错误在哪里,PHP中preg结果的评估非常奇怪。

preg_replace(
    '|http\://([\w\.-]+?)/script\.php\?fruit=([\w_-]+)|e'
    , '"http://www.$1/".$_GET["size"]."/sometext/".$fruitArray["$2"]."/";'
    , $result
);

谢谢您的努力,我已经解决了这个问题。正则表达式非常强大,但很难掌握:/ 干杯! - Matt
@Matt 正则表达式确实像你说的那样强大,但有时即使你自己写了它,它也很难被人类读懂,因此重新编写是一个好习惯。正则表达式只是一种练习...保持这种方式,一个正则表达式问题总是一个巧妙的问题。 - Felipe Buccioni

0

看起来你忘记转义 ? 了。应该是 /script.php\?,需要使用 \? 进行正确的转义,就像你提供的链接答案中所示。


糟糕,我在发布的示例中忘记做了那个了;实际代码已经正确转义。代码已更新,感谢指出问题 - 问题仍然存在。 - Matt

0

使用 $fruitArray["\$1"] 替代 $fruitArray["$1"]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接