3

假设我有一个正则表达式可以正常工作以查找文本文件中的所有 URL:

(http://)([a-zA-Z0-9\/\.])*

如果我想要的不是 URL 而是相反的 - 除了 URL 之外的所有其他文本 - 是否有一个简单的修改可以得到这个?

4

4 回答 4

8

您可以简单地搜索并用空字符串替换与正则表达式匹配的所有内容,例如在 Perls/(http:\/\/)([a-zA-Z0-9\/\.])*//g

这将为您提供原始文本中的所有内容,除了那些与正则表达式匹配的子字符串。

于 2009-07-17T01:09:43.873 回答
4

如果由于某种原因您需要纯正则表达式解决方案,请尝试以下操作:

((?<=http://[a-zA-Z0-9\/\.#?/%]+(?=[^a-zA-Z0-9\/\.#?/%]))|\A(?!http://[a-zA-Z0-9\/\.#?/%])).+?((?=http://[a-zA-Z0-9\/\.#?/%])|\Z)

我稍微扩展了一组 URL 字符 ( [a-zA-Z0-9\/\.#?/%]) 以包括一些重要的字符,但这绝不意味着准确或详尽。

正则表达式有点像怪物,所以我会尝试分解它:

(?<=http://[a-zA-Z0-9\/\.#?/%]+(?=[^a-zA-Z0-9\/\.#?/%])

第一个药水匹配 URL 的结尾。http://[a-zA-Z0-9\/\.#?/%]+匹配 URL 本身,同时(?=[^a-zA-Z0-9\/\.#?/%])断言 URL 必须后跟一个非 URL 字符,以便我们确定我们在末尾。使用前瞻,以便寻找但不捕获非 URL 字符。整个事情都被包裹在一个lookbehind(?<=...)中,以寻找它作为匹配的边界,再次没有捕获那部分。

我们还想在文件的开头匹配一个非 URL。\A(?!http://[a-zA-Z0-9\/\.#?/%])匹配文件的开头 ( \A),后跟一个否定的前瞻,以确保文件开头没有潜伏的 URL。(这个 URL 检查比第一个更简单,因为我们只需要 URL 的开头,而不是整个内容。)

这两项检查都放在括号中,并与字符OR一起 'd 。|之后,.+?匹配我们试图捕获的字符串。

然后我们来((?=http://[a-zA-Z0-9\/\.#?/%])|\Z)。在这里,我们再次使用 . 检查 URL 的开头(?=http://[a-zA-Z0-9\/\.#?/%])。文件的结尾也是一个很好的迹象,表明我们已经到了比赛的结尾,所以我们也应该使用\Z. 与第一个大组类似,我们将其用括号括起来,OR并将两种可能性放在一起。

|符号需要括号,因为它的优先级很低,因此您必须明确说明OR.

这个正则表达式严重依赖于零宽度断言(\A\Z锚点,以及环视组)。在将正则表达式用于任何严重或永久性的事情之前,您应该始终了解它(否则您可能会遇到 perl 的情况),因此您可能需要查看Start of String 和 End of String Anchors以及Lookahead 和 Lookbehind Zero-Width Assertions

当然欢迎指正!

于 2009-07-17T02:39:03.240 回答
1

如果我正确理解了这个问题,您可以使用搜索/替换...只是在您的表达式周围使用通配符,然后替换第一个和最后一个部分。

s/^(.*)(your regex here)(.*)$/$1$3/
于 2009-07-17T01:10:39.677 回答
0

我不确定这是否会完全按照您的意图工作,但它可能会有所帮助:无论您放在括号 [] 中的任何内容都将匹配。如果您将 ^ 放在括号内,即 [^a-zA-Z0-9/.] 它将匹配括号中的内容之外的所有内容。

http://www.regular-expressions.info/

于 2009-07-17T01:17:57.003 回答