懒惰的量词和前瞻
我正在使用C#验证URL的正则表达式。 现在,我需要的正则表达式不能与其他http://
不匹配,但是它是url中的第一个。 这是我第一次尝试:
(https?://.+?)/(.+?)(?!https?://)
但是这个正则表达式不起作用(甚至删除(?!https?://)
)。 以这个输入字符串为例:
http://test.test/notwork.http://test
这是我的第一个疑问: 为什么捕获组(.+?)
匹配notwork.http://test
? 懒惰的量词应该尽可能少地匹配,但为什么不直到最后呢? 在这种情况下,我肯定错过了一些东西(首先我认为它可能与回溯有关,但我不认为是这种情况),所以我阅读并找到了解决方案,即使我不确定是否是最好的解决方案因为它说
这种技术与懒惰的小星星相比没有什么优势
无论如何,这个解决方案就是钢化点。 这是我的下一次尝试:
(https?://.+?)/((?:(?!https?://).)*)
现在:这个正则表达式正在工作,但不是我想要的方式。 只有当网址有效时,我才需要匹配。
顺便说一下,我认为我还没有完全理解新正则表达式在做什么: 为什么负面预测在这之前保持不变.
而不是之后呢? 所以我试着在它后面移动它.
它似乎匹配的网址,直到找到第二个http之前的倒数第二个字符。 回到正确的正则表达式,我的假设是负面的前瞻实际上是试图检查后面的东西.
已经被正则表达式读过了,对吗?
其他解决方案已被广泛接受,但我首先更愿意理解这一点。 谢谢。
你寻求的解决方案是
(?>https?://S+?/(?:(?!https?://).)*)(?!https?://)
查看正则表达式演示
细节
(?>https?://S+?/(?:(?!https?://).)*)
- 一个原子组(不允许回溯到其子模式) https?://
- http://
或https://
S+?
- 任何一个或多个非空白字符,尽可能少,直到第一个... /
- /
符号后跟... (?:(?!https?://).)*
- 零个或多个字符(尽可能多),不会启动一系列http://
或https://
字符。 (?!https?://)
- 如果在当前位置的右侧存在http://
或https://
则匹配会失败。 (https?://.+?)/(.+?)(?!https?://)
不起作用,因为.+?
模式匹配懒惰,即它抓住它找到的第一个字符,然后让后续子模式匹配。 后面的子模式是一个负面loolahead,只有在当前位置右侧没有http://
或https://
情况下才会失败。 由于http://test.test/notwork.http://test
n
后面没有这样的子字符串,所以以n
结尾的匹配被返回,匹配成功。 如果您不告诉正则表达式引擎匹配更多,或者直到其他分隔符/模式,它不会。
脾气暴躁的令牌解决方案已经被讨论了很多。 这个答案涵盖了确切的怀疑在哪里放置的前瞻。
链接地址: http://www.djcxy.com/p/76987.html上一篇: Lazy quantifier and lookahead
下一篇: What difference does the lazy quantifier make in this specific regex?