4

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

测试用例类似于

LINDA L
LINDSAY GRIFFIN
LINDSAY LIGHTHOUSE
LINDSAY PETERSON

我想删除第一个的尾随L\b或第二个和第三个的前导L.*?\b,这应该让我知道:

LINDA
GRIFFIN
LIGHTHOUSE
PETERSON

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

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

4

4 回答 4

3

我认为这完成了你想做的事情:

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

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

((?!.*\bL$)^L.*?\b)匹配一行开头的 L,然后是单词的其余部分(.*?\b正如您所拥有的,是到达单词末尾的合理模式)。This:(?!.*\bL$)是一个否定的前瞻,如果后面的模式匹配,则阻止匹配?!\bL$在这种情况下,如果模式出现在行中的任何位置,它将阻止匹配。

反正我就是这么想的。当然是丑陋的。正如您在问题中所暗示的那样,一个更好的解决方法是使用两个单独的正则表达式模式,只有在第一个没有找到该行的匹配项时才运行第二个。

于 2013-01-07T21:31:21.670 回答
1

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

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

string“LINDA L”或“LINDSAY GRIFFIN”等在哪里?

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

于 2013-01-07T21:39:51.977 回答
1

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


用一个正则表达式来做只会让事情变得不必要地丑陋(因此难以维护)——这是一种用两个来做的方法:

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

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

第二个表达式删除了行首的所有 L 字(第一行除外,它之前没有换行符)。

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


如果您更喜欢使用 CFML 替换功能,则等效为:

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

就我个人而言,我发现另一种方式更具可读性。

于 2013-01-08T00:10:12.660 回答
0

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

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

于 2013-01-07T21:21:27.053 回答