正则表达式在第一次匹配时使用或使用第二个正则表达式?

时间:2013-01-07 20:55:42

标签: regex coldfusion

我有一个情况是我需要删除部分字符串,我想我可以使用正则表达式。

测试用例类似于

LINDA L
LINDSAY GRIFFIN
LINDSAY LIGHTHOUSE
LINDSAY PETERSON

我希望从第一个或第三个中删除第一个或前导L\b的尾随L.*?\b,这应该留给我:

LINDA
GRIFFIN
LIGHTHOUSE
PETERSON

L\b|L.*?\b删除整个第一行和第三行(空格除外),这不是我想要的。有没有办法用一个表达式做到这一点?我认为,因为第一个正则表达式匹配,它不会移动到第二个正则表达式。

谢谢大家,我们最终只使用CF条件和两个替换而不是一个复杂的正则表达式。

4 个答案:

答案 0 :(得分:3)

我认为这可以完成您想要做的事情:

(\bL$)|((?!.*\bL$)^L.*?\b)

要解释一下,(\bL$)匹配第一个模式:单词边界,然后是L,然后是行尾。

((?!.*\bL$)^L.*?\b)匹配一行开头的L,然后是单词的其余部分(.*?\b,就像你一样,是一个合理的模式来到达单词的结尾)。这样:(?!.*\bL$)是一个负前瞻,如果匹配?!后的模式,则阻止匹配。在这种情况下,如果patterm \bL$出现在该行的任何位置,它将阻止匹配。

无论如何,这就是我想出来的。当然是丑陋的。正如你在问题中暗示的那样,更好的方法是使用两个独立的正则表达式模式,只有当第一个没有找到该行的匹配时才运行第二个模式。

答案 1 :(得分:1)

@femtoRgon几乎已经得到了它,但留下了一些悬空的空白。完整的CF解决方案将是:

result = reReplace(string, "(\s*\bL$)|((?!.*\bL$)^L.*?\b\s*)", "", "ONE");

string将是“LINDA L”或“LINDSAY GRIFFIN”等。

这会对您提供的所有示例进行测试,但它对您指定的规则非常直接。

答案 2 :(得分:1)

注意:这假设您有一个字符串,并希望在相关时应用这两个操作(即第二个不依赖于第一个);如果这不是你想要的,你需要澄清这个问题。


使用一个正则表达式只是让事情变得不必要地丑陋(因而不太可维护) - 这是用两种方法做的事情:

Input.replaceFirst('\s+L(?=\n)','').replaceAll('(?<=\n)L\w+\s+','')

第一个表达式从第一行中删除L(和前面的空格)(因为我们使用的是replaceFirst,只有第一行)。

第二个表达式删除一行开头的所有L-words(第一行除外,它之前没有换行符。)

(因为在这两种情况下我们总是会\s+匹配,所以这里不需要显式的\b;如果你不想删除空格,你可以使用一个。)


如果您更喜欢使用CFML rereplace函数,那么等价物将是:

rereplace( rereplace(Input,'\s+L(?=\n)','') , '(\n)L\w+\s+' , '\1' , 'all' )

我个人认为另一种方式更具可读性。

答案 3 :(得分:0)

你应该检查条件正则表达式。

http://www.regular-expressions.info/conditional.html