我正在尝试用正则表达式替换字符串,我真的希望社区能帮助我。
我有这个字符串:
031,02a,009,a,aaa,AZ,AZE,02B,975,135
我的目标是删除这个正则表达式的相反
[09][0-9]{2}|[09][0-9][A-Za-z]
即
a,aaa,AZ,AZE,135
(查看实际效果:http://regexr.com?3795f)
我的最终目标是preg_replace
第一个字符串只得到
031,02a,009,02B,975
(查看实际效果:http://regexr.com?3795f)
我对所有解决方案都持开放态度,但我承认如果可能的话,我真的很喜欢用 preg_replace
来解决这个问题(这变成了一种个人挑战)
感谢大家的帮助!
最佳答案
正如@Taemyr 在评论中指出的那样,我之前的解决方案(使用回顾断言)是不正确的,因为即使子字符串并不总是 3 个字符,它也会一次消耗 3 个字符。
让我们使用先行断言来解决这个问题:
'/(^|,)(?![09][0-9]{2}|[09][0-9][A-Za-z])[^,]*/'
以上匹配字符串或逗号的开头,然后检查后面的内容是否不匹配您指定保留的两种形式之一,并且如果此条件通过,则匹配尽可能多的非逗号字符。
但是,这与@anubhava 的解决方案相同,这意味着它具有相同的弱点,因为它在某些情况下可能会留下前导逗号。参见 this Ideone demo .
ltrim
逗号是到达那里的干净方式,但话又说回来,如果您正在寻找“干净的方式”,您不会尝试使用单个 preg_replace
开始吧?您的问题是是否可以在不使用任何其他 PHP 函数的情况下执行此操作。
答案是肯定的。我们可以采取
'/(^|,)foo/'
和分发交替,
'/^foo|,foo/'
这样我们就可以添加我们希望捕获的额外逗号仅在第一种情况,即
'/^foo,|,foo/'
当我们用实际的正则表达式替换 foo
时,这将是一个毛茸茸的表达式,不是吗。值得庆幸的是,PHP 支持 recursive patterns , 这样我们就可以将上面的内容重写为
'/^(foo),|,(?1)/'
就是这样。用 foo
代替它是什么,我们得到
'/^((?![09][0-9]{2}|[09][0-9][A-Za-z])[^,]*),|,(?1)/'
这确实有效,如 this second Ideone demo 所示.
不过,让我们在这里花些时间来简化您的表达。 [0-9]
等同于\d
,可以通过添加/i
来进行不区分大小写的匹配,如下所示:
'/^((?![09]\d{2}|[09]\d[a-z])[^,]*),|,(?1)/i'
您甚至可以压缩内部交替:
'/^((?![09]\d(\d|[a-z]))[^,]*),|,(?1)/i'
关于php - 用于 PHP 的正则表达式看起来很简单但是让我很痛苦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20090093/