为什么正则表达式将文件名与扩展名分开不适用于ColdFusion?

ete*_*rps 2 regex coldfusion coldfusion-9

我正在尝试在ColdFusion中检索没有扩展名的文件名.我使用以下功能: REMatchNoCase( "(.+?)(\.[^.]*$|$)" , "Doe, John 8.15.2012.docx" );

我希望这返回一个数组,["Doe, John 8.15.2012","docx"] 但是我总是得到一个包含一个元素的数组 - 整个文件名:["Doe, John 8.15.2012.docx"]

我在rexv.org上尝试了上面的正则表达式字符串,它按预期工作,但不在ColdFusion上.我从这个SO问题得到了字符串:正则表达式:一次性获取没有扩展名的文件名?

ColdFusion使用不同的语法吗?或者我做错了什么?

谢谢.

Pet*_*ton 8

为什么你没有得到预期的结果......

您获得具有整个文件名的单项数组的原因是因为您的模式匹配整个文件名,并匹配一次.

捕捉两组,但复赛返回匹配的阵列,而不是捕获组阵列,这样你就不会看到这些组.

如何解决问题......

如果您正在处理简单文件(即没有.htaccess或类似),那么最简单的解决方案就是使用......

ListLast( filename , '.' )
Run Code Online (Sandbox Code Playgroud)

....只获取文件扩展名并获取没有扩展名的名称,你可以做...

rematch( '.+(?=\.[^.]+$)' , filename )
Run Code Online (Sandbox Code Playgroud)

这使用前瞻来确保在字符串的末尾有一个.后跟至少一个非.,但是(因为它是一个预测)它被排除在匹配之外(所以你只在你的匹配中得到预扩展部分) .

要处理未扩展的文件(例如.htaccess或者README),你可以修改上面的正则表达式.+(?=(?:\.[^.]+)?$),基本上做同样的事情,除了使扩展名可选.但是,没有一种简单的方法可以为这些方法更新ListLast方法(猜测你需要检查len(extension) LT len(filename)-1或类似).

(可选)访问捕获的组...

如果你想获得实际捕获的组,在CF中最接近的本机方法是使用refind函数,第四个参数设置为true - 但是,这只给你位置和长度 - 要求你使用mid到自己提取它们.

出于这个原因(在许多其他人中),我已经为CF创建了一个改进的正则表达式实现,称为cfRegex,它允许您直接返回组文本(即不用中间乱码).

如果您想使用cfRegex,您可以使用原始模式,如下所示:

RegexMatch( '(.+?)(\.[^.]*$|$)' , filename , 1 , 0 , 'groups' )
Run Code Online (Sandbox Code Playgroud)

或者使用命名参数:

RegexMatch( pattern='(.+?)(\.[^.]*$|$)' , text=filename , returntype='groups' )
Run Code Online (Sandbox Code Playgroud)

然后返回一个匹配数组,每个元素内都是该匹配的捕获组的数组.

如果你正在处理被捕获组的大量正则表达式工作,cfRegex肯定比使用CF的re方法更好.

如果你关心的只是获得扩展名和/或扩展名的文件名,那么前面的例子就足够了.