我想在以下类型的字符串中搜索模式。
我有这两种模式
"<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)的文件名
任何想法都会有很大的帮助。
答案 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核心中。