gpt4 book ai didi

regex - Perl:不包含PATTERN的匹配字符串

转载 作者:行者123 更新时间:2023-12-03 18:14:48 29 4
gpt4 key购买 nike

在使用Perl正则表达式将字符串切成可用的片段时,我需要匹配除特定模式以外的所有内容。在Perl Monks上找到此提示后,我解决了它:

/^(?:(?!PATTERN).)*$/;    # Matches strings not containing PATTERN

尽管我解决了最初的问题,但对于它的实际工作方式却一无所知。我检查了 perlre,但是它太正式了以至于无法掌握。

Regular expression to match a line that doesn't contain a word?在理解上有很大帮助,但是为什么我的示例中的 .?:以及外部括号如何工作?

有人可以分解正则表达式并用简单的词来解释它是如何工作的吗?

最佳答案

逐步构建它(并假设字符串或PATTERN中没有换行符):
这匹配任何字符串:

/^.*$/
但是我们不希望 .与以PATTERN开头的字符匹配,因此请替换
.
(?!PATTERN).
这会使用否定的超前功能,它在不实际消耗任何字符串的情况下测试给定的模式,仅在模式在字符串中的给定点不匹配时才成功。所以就像说:
if PATTERN doesn't match at this point,
match the next character
需要对字符串中的每个字符执行此操作,因此 *用于从字符串开头到结尾匹配零次或多次。
为了使 *适用于否定的look-ahead和 .的组合,而不仅仅是 .,它需要用括号括起来,并且由于没有理由要捕获,因此它们应该使用非捕获括号 (?: ):
(?:(?!PATTERN).)*
放回 anchor ,以确保我们在字符串的每个位置进行测试:
/^(?:(?!PATTERN).)*$/
请注意,此解决方案作为较大匹配项的一部分特别有用。例如匹配任何带有 foo和更高版本的 baz但之间没有 bar的字符串:
/foo(?:(?!bar).)*baz/
如果没有这样的考虑,您可以简单地执行以下操作:
/^(?!.*PATTERN)/
检查PATTERN是否与字符串中的任何地方都不匹配。
关于换行符:您的正则表达式和换行符有两个问题。首先, .不匹配换行符,因此 "foo\nbar" =~ /^(?:(?!baz).)*$/不匹配,即使字符串不包含baz。您需要添加/s标志以使 .匹配任何字符; "foo\nbar" =~ /^(?:(?!baz).)*$/s正确匹配。其次, $不仅在字符串末尾匹配,还可以在字符串末尾的换行符之前匹配。因此 "foo\n" =~ /^(?:(?!\s).)*$/s确实匹配,即使字符串包含空格并且您试图仅匹配不带空格的字符串也是如此。 \z始终仅在末尾匹配,因此 "foo\n" =~ /^(?:(?!\s).)*\z/s无法正确匹配实际上包含 \s的字符串。因此正确的通用正则表达式为:
/^(?:(?!PATTERN).)*\z/s

关于regex - Perl:不包含PATTERN的匹配字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23403494/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com