正则表达式:多个/单个字符匹配问题

6

我正在动态地创建一个正则表达式。

我希望它能匹配以下内容:

lem
le,,m
levm
lecm

基本上,"lem"之前的m可以有任意数量的,,或者任意一个字符。目前我的文本是:

le[\,]{0,}[.]?m

您可以在http://regexr.com?303ne上查看它。

它应该匹配每个,但不包括第三个。

更新:我弄清楚了:

le[\,]{0,}.?m

您能描述哪些输入匹配,哪些不匹配吗? - Carl Norum
好的,我添加了一些输入示例。 - LemonPie
@LemonPie:那“LemonPie”呢?它是否匹配?也就是说,重复的字符必须连续才能匹配失败吗? - Marcelo Cantos
@Marcelo Cantos:看看我的RexExr链接。它应该匹配每一个,除了第三个。 - LemonPie
@LemonPie:感谢你的链接,但里面并没有解释清楚。 - zerkms
你的解决方案不符合规格,而且过于复杂。请查看我的答案。 - PointedEars
3个回答

12
无论何时在正则表达式中想到"或",都应该从多选结构开始:

Whenever you think "or" in Regular Expressions, you should start with alternation:

a|b

匹配ab中的任意一个。所以

字符列表中的任意数量字符 或者 任意一个字符

可以直接翻译为上述内容。

[...]*|.

...代表需要匹配的字符列表(一个字符类)。如果你在长表达式中使用它,你需要使用括号,因为串联绑定更强(优先级更高)比交替:

le([,]*|.)m

由于字符类只有一个项,我们可以简化此代码:

le(,*|.)m
请注意,默认情况下,. 代表的是除换行符以外的任何字符。

3
只是提供信息 - 对于回答第一版问题的答案进行负投票并不礼貌。这并不是我的错,是提问者改变了问题。 - zerkms
@zerkms 根据移动界面显示,OP 最后更新于1小时前。您最后更新于59分钟前。 - PointedEars
2
所以我一直都应该按F5键来查看OP是否改变了他的想法吗?我一直在回答原始问题,逐步获取细节(你知道的-这不是我的错,原始问题和所有其他编辑并没有立即包含所有必要的信息),而最后我却遭到了负分…完美。 - zerkms
这里的m是不必要的模式修饰符,因为模式中没有^$锚定符。 - mickmackusa

2
这个怎么样:
le(,*|.?)m

它应该做你想要的事。


这里的m是不必要的模式修饰符,因为模式中没有^$锚定符。 - mickmackusa

1
这个怎么样?
([^,])(?=\\1)

但这个做的是相反的 :-) 不确定对你是否可行

更新:

这应该适合你:

~^(?:,|([^,])(?!\\1))+$~

不确定您需要哪种方言,但它在PCRE中有效:http://ideone.com/6Q3Wk

更新2:

相同的正则表达式包含在另一个中。

$r = '(?:,|([^,])(?!\\1))+';
var_dump(preg_match('~le' . $r . 'm~', 'leem'));

在这种情况下,最终表达式变为:le(?:,|([^,])(?!\\1))+m,其中lem不作修改地添加到我的周围。

似乎匹配除了逗号以外的每个字符。 - LemonPie
@LemonPie:它做相反的工作。如果你能够反转结果 - 那么它就完美地符合任务。 - zerkms
我不相信它适用于我的目的,因为我正在制作一个脏话过滤器。 - LemonPie
@LemonPie:为什么leem应该匹配?你说:“假设中间可以匹配任意数量的逗号或任意字符中的1个”,但“不匹配,因为e只能出现一次”。 - zerkms
2
@LemonPie: 你要“制作一个脏话过滤器”?又一个?祝你好运,不要遇到Scunthorpe问题! - johnsyweb
显示剩余9条评论

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