常见问题的简单解决方案
我读过的所有答案都离题,过于复杂,或者只是不正确。这个问题是一个常见的问题,正则表达式提供了一个简单的解决方案。
分解一般问题
-
字符串
-
子字符串
- 字符串中有一个由几个字符组成的子字符串。通常这是一个文件扩展名(即
.c、.ts或.json)或顶级域(即.com、@987654327 @ 或 .io),但它可能像 MC Donald's Mulan Szechuan Sauce 一样任意。关键是,它可能并不总是那么简单。
-
之前的差异(最重要的部分)
-
变异前 是一个或多个任意字符,总是出现在子字符串之前。在这个问题中,之前的方差是未知数量的空白。这是一个差异,因为需要匹配的空白数量会有所不同(或具有动态数量)。
参考问题描述解决方案
(解决方案第 1 部分)
在使用正则表达式时,通常需要逆向工作。
我们将从上述问题的结尾开始,然后向后工作;我们将从 The Before Variance(或 #3)开始
因此,如上所述,The Before Variance 是未知数量的空白。我们知道它包含空白,但我们不知道有多少,因此我们将使用 Any Whitespce 的元序列 和 一个或多个量词。
-
“任何空白”的元序列是 \s。
-
“一个或多个”量词是+
所以我们从...开始
注意:在 ECMAS 正则表达式中,/ 字符就像字符串周围的引号。
const regex = /\s+/g
我还加入了g 来告诉引擎将全局标志设置为真。为简洁起见,我不会解释标志,但如果您不知道全局标志的作用,您应该使用 DuckDuckGo。
(解决方案第 2 部分)
请记住,我们是在逆向工作,所以接下来要关注的部分是子字符串。在这个问题中它是.com,但作者可能希望它与具有方差的值匹配,而不仅仅是静态字符串.com,因此我将在下面详细讨论,但为了保持专注,我们现在可以使用.com。
我们有必要在这里使用一个称为零长度断言的概念。我们需要一个“零长度断言”,因为我们有一个重要的子字符串,但不是我们想要匹配的。 “零长度断言”允许我们移动正则表达式引擎正在查看的字符串中的点,而无需匹配任何字符即可到达那里。
我们要使用的Zero-Length Assertion叫做LOOK AHEAD,它的语法如下。
前瞻语法:(?=Your-SubStr-Here)
我们将使用前瞻来匹配分配给前瞻的模式之前的方差,这将是我们的子字符串。结果如下所示:
const regex = /\s+(?=\.com)/gi
我添加了不敏感标志来告诉引擎不关心字母的大小写,换句话说;正则表达式/\s+(?=\.cOM)/gi
与/\s+(?=\.Com)/gi 相同,两者都与:/\s+(?=\.com)/gi &/或 /\s+(?=.COM)/gi 相同。只要设置了i 标志,“刚刚列出”的每个正则表达式都是等效的。
我在上面提到过使用比 .com 变化更大的子字符串。
例如,您可以使用(\s*)(?=\.\w{3,})。
这个正则表达式的问题在于,即使它匹配.txt、.org、.json 和.unclepetespurplebeet,该正则表达式也不安全。使用问题的字符串时...
"as.asd.sd fdsfs. dfsd d.sdfsd. sdfsdf sd .COM"
例如,您可以在LINK HERE (Regex101) 看到字符串中有 3 行。这些行表示子字符串的前瞻断言返回 true 的区域。每次断言为真时,都会产生不正确的最终匹配的可能性。虽然最后只返回了一个匹配,而且它是正确的匹配,但当在生产中运行的程序或网站中实现时,您几乎可以保证正则表达式不仅会失败,而且会继续失败得可怕,你会讨厌它。