PHP中的正则表达式:替换字符串之间的文本

时间:2014-08-19 19:02:34

标签: php regex

好的,我在解决的问题上取得了一些进展,但需要一些小故障的帮助。

我需要从第一个数字前的特定路径images/prices/中的文件名中删除所有字符,除了from_之外的地方,在这种情况下删除文件名中的所有字符BEFORE {{1 }}

示例:

from_

我做了什么:

BEFORE                                AFTER
images/prices/abcde40.gif           > images/prices/40.gif
images/prices/UgfVe5559.gif         > images/prices/5559.gif
images/prices/wedsxcdfrom_88457.gif > images/prices/from_88457.gif

我的预期输出是:

$pattern = '%images/(.+?)/([^0-9]+?)(from_|)([0-9]+?)\.gif%';
$replace = 'images/\\1/\\3\\4.gif';
$string = "AAA images/prices/abcde40.gif BBB images/prices/wedsxcdfrom_88457.gif CCC images/prices/UgfVe5559.gif DDD";
$newstring = str_ireplace('from_','733694521548',$string);
while(preg_match($pattern,$newstring)){
    $newstring=preg_replace($pattern,$replace,$newstring);
}
$newstring=str_ireplace('733694521548','from_',$newstring);
echo "Original:\n$string\n\nNew:\n$newstring";

但相反,我得到了:

AAA images/prices/40.gif BBB images/prices/from_88457.gif CCC images/prices/5559.gif DDD"

最后两条路径中缺少路径的AAA images/prices/40.gif BBB images/from_88457.gif CCC images/5559.gif DDD 部分。

请注意,prices/AAA等部分只是占位符。实际上,路径分散在解析为字符串的原始HTML文件中,因此我们不能依赖于要替换的文本出现之间的任何模式。

另外,我知道我使用替换BBB的方法是hacky,但这纯粹是为了本地文件操作而不是生产服务器,所以我没关系。但是,如果有更好的方法,我全都耳朵!

感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

您可以使用外观断言:

preg_replace('~(?<=/)(?:([a-z]+)(?=\d+\.gif)|(\w+)(?=from_))~i', '', $value);

<强>解释

(?<=/)          # If preceded by a '/':
(?:             # Begin group
 ([a-z]+)       #   Match alphabets from a-z, one or more times
 (?=\d+\.gif)   #   If followed followed by digit(s) and '.gif'
 |              #   OR
 (\w+)          #   Match word characters, one or more times
 (?=from_)      #   If followed by 'from_'
)               # End group

<强>可视化:

Image from debuggex

<强>代码:

$pattern = '~(?<=/)(?:([a-z]+)(?=\d+\.gif)|(\w+)(?=from_))~i';
echo preg_replace($pattern, '', $string);

Demo

答案 1 :(得分:0)

$arr = array(
    'images/prices/abcde40.gif',
    'images/prices/UgfVe5559.gif',
    'images/prices/wedsxcdfrom_88457.gif'
);

foreach($arr as $str){
    echo preg_replace('#images/prices/.*?((from_|\d).*)#i','images/prices/$1',$str);
}

<强> DEMO

编辑:

$str = 'AAA images/prices/abcde40.gif BBB images/prices/wedsxcdfrom_88457.gif CCC images/prices/UgfVe5559.gif DDD';

echo preg_replace('#images/prices/.*?((from_|\d).*?\s|$)#i','images/prices/$1',$str), PHP_EOL;

答案 2 :(得分:0)

您可以使用此正则表达式进行替换:

^(images/prices/)\D*?(from_)?(\d+\..+)$

并使用此表达式进行替换:

$1$2$3

RegEx Demo

<强>代码:

$re = '~^(images/prices/)\D*?(from_)?(\d+\..+)$~m'; 
$str = "images/prices/abcde40.gif\nimages/prices/UgfVe5559.gif\nimages/prices/wedsxcdfrom_88457.gif";     
$result = preg_replace($re, '$1$2$3', $str);

答案 3 :(得分:0)

您也可以尝试使用 Lookaround 。只需用空白字符串替换。

(?<=^images\/prices\/).*?(?=(from_)?\d+\.gif$)

regex101 demo

示例代码:(直接来自网站上方)

$re = "/(?<=^images\\/prices\\/).*?(?=(from_)?\\d+\\.gif$)/m";
$str = "images/prices/abcde40.gif\nimages/prices/UgfVe5559.gif\nimages/prices/wedsxcdfrom_88457.gif";
$subst = '';

$result = preg_replace($re, $subst, $str);

如果字符串不是多行,则使用\b作为字边界而不是^$来匹配行/字符串的开头和结尾。

(?<=\bimages\/prices\/).*?(?=(from_)?\d+\.gif\b)