查找最后一个跟随着空格的字母字符的位置所需的正则表达式是什么?

3

我正在使用ColdFusion 10。我很少需要使用正则表达式,确实需要一些帮助。

我有一些冗长的内容(最多8000个字符)并想创建一个预览。在达到某个长度之后(我将在其他地方定义),我想找到最后一个后面跟着空格的字母字符。我将删除该字符之后的所有内容。然后我会添加省略号(...)。

MyString = "The lazy brown fox is not a dog."

在这种情况下,我会删除在“dog”之前的“a”后面的所有内容。
MyString = "There are 123 boxes on up the hill, says that 612 guy."

在这种情况下,我会删除在“612”之前的“that”后面的所有内容。
MyString = "I fell down the stairs on June 30th, 1962."

在这种情况下,我会删除在“6月30日”之后的所有内容。
我应该使用什么正则表达式来查找最后一个后面跟着空格的字母[a-Z]字符位置?
MyReg = "";
LastPosition = reFindNoCase(MyReg, MyString);

1
不确定ColdFusion语法,但形式为/^.*([a-zA-Z]) /的正则表达式应该可以解决问题。 .*是贪婪的,因此它会尽可能多地吃掉字符(请注意,']'和'/'之间有一个空格)。 字符将在捕获组中。 - Jim Mischel
前置 - (动词)1. 在时间上先于(某事物)。2. 在顺序或位置上先于(某事物):“阅读在食谱之前的章节”。在“dog”之前的“a”后面的所有内容都将成为一个空格。这是您的意思吗? - JDB
是的,在第一个例子中,“dog”之前的“a”后面的所有内容都将成为一个空格。我想知道那个单独空格的位置。是否有一个正则表达式可以返回该位置? - Evik James
2个回答

3

如果你正在处理长字符串,正则表达式需要扫描整个字符串才能到达末尾,而从末尾开始并向前工作可能更有效率。

像这样:

LastPos = len(String);

while( LastPos > 1 )
{
    LastPos = String.lastIndexOf(' ',LastPos-1);

    if ( mid(String,LastPos,1).matches('[a-zA-Z]') )
        break;

}

NewString = left(String,LastPos);

这个想法是不断向后查找空格,并在前一个字符是字母(或到达字符串开头)时停止循环。
如果你真的想要一个正则表达式解决方案,只需执行以下操作:
NewString = rematch('.*[a-zA-Z] ',MyString)[1];

为了得到这个位置,您需要使用len(NewString)
(如果涉及换行符,则需要在表达式开头加上(?s)以便点号匹配它们。)

3

我不确定 REFindNoCase,但我认为你可以尝试使用 REReplaceNoCase。我希望 CF 可以像大多数正则表达式引擎一样接受返回的引用:

REReplaceNoCase(MyString, "(.*\b[a-zA-Z]+\b)\s.*", "$1", ALL);

编辑:对于反向引用,需要使用反斜杠而非美元符号:

REReplaceNoCase(MyString, "(.*\b[a-zA-Z]+\b)\s.*", "\1", ALL);

如果一切顺利,你应该会得到类似于这样的东西。

.*匹配除换行符以外的任何字符,\b匹配单词边界,[a-zA-Z]+用于字母字符,\s用于它后面的空格。

在这里,第一个.*的贪婪性被利用起来,尽可能多地捕获,直到最后一个单词后跟一个空格。

我想你可以在$1之后添加省略号,就像这样:

REReplaceNoCase(MyString, "(.*\b[a-zA-Z]+\b)\s.*", "\1 (...)", ALL)

如果你只想使用 REFind(),你可以尝试使用以下代码:
REFindNoCase("[A-Za-z](?:\s\d+|\w+,)*\s[^\s]+\.$", MyString);

请注意,我还没有对此进行针对其他可能情况的测试,但我尝试过一些在上述方法中不起作用,但在这种方法中可以实现的方式。
REFindNoCase("[A-Za-z](?:\s\d+|\s?\w+[,.-]+)*\s[^\s]+[.\s]*$", MyString);

以下是几个测试对象:链接

REFind将给出最后一个字母字符的位置。您可以加1来得到原始字符串中空格的位置。


1
+1 - ColdFusion 可以处理回溯引用,但我认为其语法略有不同。在使用回溯引用时,需使用\1 而非 $1 - Miguel-F
1
回复:我希望CF能像大多数正则表达式引擎一样收回引用:是的。它在内部使用Apache ORO(https://dev59.com/HU7Sa4cB1Zd3GeqP3nNt#3047304)。因此,反向引用表示为“\1”,而不是“$1”。(编辑:@Miguel-F 哎呀,注意了,我们想到一块儿去了;-) - Leigh
@Leigh - 哈!我刚刚编辑了我的评论,加入了不同的符号,看到你也加了。 - Miguel-F
@EvikJames - 然后只需使用 REFind()REFindNoCase() 替换 REReplaceNoCase()(您不需要第三个参数替换字符串)。这是 REFind 的文档REFindNoCase 的文档(当您使用正则表达式包含/排除大小写时,我真的不知道两者之间的区别)。 - Miguel-F
1
@EvikJames,使用REFind()并不简单,你可能会遇到很多异常情况。看看我更新后的答案是否适合你。 - Jerry
显示剩余8条评论

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