我正在帮助解决我在preg_replace php函数中遇到的问题。 我制作了一个正则表达式来匹配首字母缩略词,abreviation,...其中一些使用短划线或点来分隔字母,有些则不是。
\p{Lu}+(\p{Zs}?[.-]\p{Zs}?){1,10}
我的目的是用#替换短划线和点,我试图使用:
$re = '/\p{Lu}+(\p{Zs}?[.-]\p{Zs}?){1,10}/i';
$str ='normal text C.G. P- U.T.O .K.L. another normal text';
$subst = '${1}#';
$result = preg_replace($re, $subst, $str);
根据我的理解,这应该替换第一个捕获组(破折号或点)并用#替换它。但事实上,它取代了这封信。
例如,在此字符串 C.G中。 P-U.T.O .K.L。我希望 CGPUTOKL ,但实际上我有。#。 # - #。#。#。#。#..
您可以访问以下所有内容:https://regex101.com/r/gkeGiw/4。
你能告诉我哪里错了(以及为什么)?
提前谢谢你,
问候,
查尔斯
答案 0 :(得分:0)
您需要preg_replace_callback
。正如@SebastianProske所说,你抓住了你不想要的东西。但是,您不能在重复模式中捕获您想要的位,因为最后一个匹配会覆盖所有先前的匹配,因此您只能获得每个匹配的最后一个字母。您应匹配整个首字母缩略词,然后擦除匹配。假设每个缩写最少2个字母:
$text_abbreviation_normalised = preg_replace_callback(
'/\p{Lu}(?:(?:\p{Zs}*[.-]\p{Zs}*)?\p{Lu}){1,9}(?:\p{Zs}*\.)?/',
function($matches) {
return preg_replace('/\P{Lu}+/', '', $matches[0]);
},
$text
);
https://regex101.com/r/gkeGiw/7的解释。
技术上可以在没有回调的情况下做到这一点,但正则表达式将是 hideous 。