使用正则表达式的特定搜索模式

时间:2014-03-07 10:34:08

标签: regex perl

我想在以下类型的字符串中搜索模式。

我有这两种模式

"<deliveries!ntg5!intel!api!ntg5!avt!tuner!src>CDAVTTunerTVProxy.cpp"

"<.>api/sys/mocca/pf/comm/component/src\HBServices.hpp" 

我想从上面的模式中提取文件名

我尝试了以下

if(m/(\|>[0-9a-zA-Z_]\.cpp"$|\.hpp"$|\.h"$|\.c")$/){

上面的表达式未列出" >xxxxx.cpp"(或.hpp,或.h或.c)的文件名

任何想法都会有很大的帮助。

2 个答案:

答案 0 :(得分:0)

请试试这个正则表达式:

m/([0-9a-zA-Z_]+\.(?:cpp|hpp|h|c))$/

这个正在查找字符串末尾的扩展名cpp,hpp,h或c(使用$),然后在句点(.)之前查找文件名扩展

答案 1 :(得分:0)

你的正则表达式中有一些错误

if(m/(\|>[0-9a-zA-Z_]\.cpp"$|\.hpp"$|\.h"$|\.c")$/){

我认为\|>应该匹配\>,但这是不正确的。它会尝试匹配管道|后跟>。反斜杠用于转义字符,因此如果要匹配文字反斜杠,则需要转义它:\\。这是使用替换的错误方法(参见下文),并且有一种更好的方法,即使用字符类:[\\>]

[0-9a-zA-Z_]是一个由\w表示的字符类,因此使用它可以使正则表达式更具可读性。此外,您只匹配一个字符。如果您想要匹配更多,则需要提供量词,例如+,这在这种情况下是合适的。量词+表示匹配1次或更多次。

您的替换|混淆了。除非您正确地对它们进行分组,否则它们将用于匹配整个字符串。你的正则表达式现在可以捕获如下字符串:

|>A.cpp"
.hpp"
.c"

这不是你想要的。如果要将不同的扩展名应用于主文件名正文,则必须正确对备用扩展名进行分组:

\w+\.(?:cpp|hpp|h|c)"$

使用不捕获(?: ... )的括号适合分组。正如您所看到的,没有必要重复字符串中对于所有扩展名都相同的部分。

那么我们最终会得到什么?

/([\\>]\w+\.(?:cpp|hpp|h|c)")$/

虽然我不认为您真的想要在匹配中包含前导[\\>],或者尾随"。所以更恰当的是

/[\\>](\w+\.(?:cpp|hpp|h|c))"$/

请注意,正如我在评论中所说,如果这些是路径,则需要使用一个模块,并且您想要提取文件名。从版本5开始,File::Basename包含在Perl核心中。