php - 用于 PHP 的正则表达式看起来很简单但是让我很痛苦

标签 php regex

我正在尝试用正则表达式替换字符串,我真的希望社区能帮助我。

我有这个字符串:

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/

相关文章:

php - 从表中获取用户,其中 group=另一个表行的组,但我有其他表行的 id

php - 在一个时间范围内多次运行 PHP crone

javascript - 来自 PHP 的最新 XML 文件响应未加载到 Javascript 中

JavaScript 正则表达式 - 检查数字匹配的数量

java - 替换 Java 中的空格和其他一些字符

php - 检查是否已经是用户然后插入数据库php

php - MySQL 查询中表名周围反引号的重要性

python - 使用正则表达式从文本文件中提取数字

java - 使用java模式匹配器提取特定的链接模式

regex - .*(点星)如何工作?