如果字符串更长,Perl正则表达式部分匹配?

时间:2013-08-06 22:47:04

标签: regex perl

我有一个嵌套哈希树,每个哈希都包含一个名称,就像带有文件的嵌套目录一样。如果我在运行时获得外部提供的regexp(我不想分析),我如何找到在哪些子树中查找匹配项。匹配的路径可能是

形式
"$x{name}/$x{subdir}{name}/$x{subdir}{subdir}{name}"

但是,因为可能有成千上万的哈希值,所以我只想在两者都部分匹配的情况下尝试:

"$x{name}"
"$x{name}/$x{subdir}{name}"

或者甚至更好,如果第一部分匹配然后尝试直接继续第二部分然后第三部分,有点像/\G.../g,除了正则表达式来自其他地方。而且我需要回溯以查看所有其他部分匹配的子目录。

PCRE g_match_info_is_partial_match听起来正是我正在寻找的,但尽管该名称中的“Perl”,即使5.18源也似乎不包含此内容。我实际上想要向后兼容5.8.0。

这个问题的背景是将regexp语法引入makepp。我们基本上是为模式做的,但由于它们的琐碎语法,这很容易。请注意,我们会缓存我们找到的文件,并可以在出现时处理更多文件。这使得makepp能够匹配以后可能构建的文件,因为它也将规则的输出放入树中。

1 个答案:

答案 0 :(得分:0)

Perl正则表达式和PCRE相互激励,但并不是真正兼容,而且完全不一样。 Perl使用自定义正则表达式引擎。

正则表达式匹配,或者不匹配。如果正则表达式失败,则无法确定匹配失败的位置,除非正则表达式是以报告位置的方式编写的。

唯一可行的解​​决方案是需要一个正则表列表,每个级别一个。

否则,您可以要求用户以部分匹配的方式编写正则表达式。在这种情况下,必须重写正则表达式qr|foo/bar\.txt$|

qr|\A /                # anchor at start
  (?: [^/]*/       )*  # match as many directories as neccessary
  (?: foo/bar\.txt )?  # maybe match an ending foo/bar.txt
\z|x                   # anchor at end

示例:

for ("/a/", "/a/b/", "/a/b/foo/", "/a/b/foo/bar.txt", "/a/b/foo/baz.txt", "/a/bar.txt") {
  say qq("$_" -- ), /$regex/ ? "matches" : "doesn't match";
}

输出:

"/a/" -- matches
"/a/b/" -- matches
"/a/b/foo/" -- matches
"/a/b/foo/bar.txt" -- matches
"/a/b/foo/baz.txt" -- doesn't match
"/a/bar.txt" -- doesn't match

显然,这并不会以任何方式减少此正则表达式的搜索空间。

您可以以适用于您的应用程序的方式旋转它。根据您的应用提供的保证,您可以将原始正则表达式自动转换为“始终”匹配的内容。