懒惰量词和向前看
我正在使用C#验证网址的正则表达式。现在,我需要的正则表达式不能与其他http://
匹配,但是它是url中的第一个。这是我第一次尝试:懒惰量词和向前看
(https?:\/\/.+?)\/(.+?)(?!https?:\/\/)
但这正则表达式不工作(甚至消除(?!https?:\/\/)
)。就拿这个输入字符串:
http://test.test/notwork.http://test
这是我的第一个疑问:为什么不捕获组(.+?)
比赛notwork.http://test
?懒惰的量词应该尽可能少地匹配,但为什么不直到最后呢?在这种情况下,我肯定错过了一些东西(首先我认为它可能与回溯有关,但我不认为是这种情况),所以我读this并找到了解决方案,即使我不确定是否是最好的因为它说,
该技术存在任何优势来相会点星级
总之,该解决方案是回火点。这是我的下一个尝试:
(https?:\/\/.+?)\/((?:(?!https?:\/\/).)*)
现在:这个正则表达式工作,但不是我想要的方式。 只有当网址有效时,我才需要一个匹配。
顺便说一句,我想我已经不能充分理解新的正则表达式是这样做的:为什么负先行的.
前停留,而不是之后呢? 所以我试图在.
之后移动它,它似乎匹配url直到找到第二个http之前的倒数第二个字符。回到正确的正则表达式,我的假设是负面的前瞻实际上是试图检查.
已经读过的正则表达式,这是正确的吗?
其他解决方案已被广泛接受,但我首先更愿意理解这一点。谢谢。
你所寻求的解决方案是
(?>https?://\S+?/(?:(?!https?://).)*)(?!https?://)
详细
-
(?>https?://\S+?/(?:(?!https?://).)*)
- 的原子团(允许无回溯到它的子模式)匹配-
https?://
-http://
或https://
-
\S+?
- 任何1个或多个非空白字符,尽可能少,直至第一... -
/
-/
符号随后与... -
(?:(?!https?://).)*
- 零个或多个字符(尽可能多),它们不会启动一系列http://
或https://
字符。
-
-
(?!https?://)
- 负先行失败的比赛,如果有http://
或https://
立即到当前位置的右侧。
的(https?:\/\/.+?)\/(.+?)(?!https?:\/\/)
因为.+?
图案匹配懒惰地不工作,即它抓住它找到的第一个字符,然后让后续子模式匹配。随后的子模式是仅在当前位置右侧没有http://
或https://
的情况下才失败匹配的负面loolahead。由于在http://test.test/notwork.http://test
中的n
之后没有这样的子字符串,所以以n
结尾的匹配被返回,所以匹配成功。如果您不告诉正则表达式引擎匹配更多,或者直到其他分隔符/模式,它不会。
脾气暴躁的标记解决方案已被讨论了很多。 this answer中涵盖了确切的怀疑在何处放置预览。
这个问题太广泛了。第二个“怀疑”在[这里]解释(https://*.com/questions/30900794/tempered-greedy-token-what-is-different-about-placing-the-dot-before-the-negat)。至于第一个,你只需要使用* positive * lookahead和''''替代('(。*?)(?= https?:\/\/| $)')。一个'。+?'匹配1个字符,并且不需要匹配更多,因为它是懒惰的。 –
你是什么意思“只有当网址有效时我需要一个匹配”? –
关于第一个疑问:我应该使用'$',这样懒惰的量词可以匹配直到输入结束,对吗?为什么没有暗示?我读到你的回答关于脾气暴躁的标记*,它肯定更清楚。只有当url不包含其他'http://'时,我才需要一个匹配,而当我使用当前的正则表达式时,如果包含'http://',我也有匹配。顺便说一句,谢谢你的答案。 –