懒惰的量词和前瞻

Mar*_*ara 6 c# regex negative-lookahead

我正在研究用于在C#中验证URL的正则表达式.现在,我需要的正则表达式必须与http://url中的第一个正则表达不匹配.这是我的第一次尝试:

(https?:\/\/.+?)\/(.+?)(?!https?:\/\/)
Run Code Online (Sandbox Code Playgroud)

但这个正则表达式不起作用(甚至删除(?!https?:\/\/)).以此输入字符串为例:

http://test.test/notwork.http://test
Run Code Online (Sandbox Code Playgroud)

这是我的第一个疑问:为什么捕获组不(.+?)匹配notwork.http://test?懒惰的量词应尽可能少匹配,但为什么不到最后?在这种情况下,我当然错过了一些东西(首先我认为它可能与回溯相关,但我不认为是这种情况),所以我读了这个并找到了解决方案,即使我不确定是最好的因为它说

这种技术没有优于懒惰的点星

无论如何,那个解决方案就是淬火点.这是我的下一次尝试:

(https?:\/\/.+?)\/((?:(?!https?:\/\/).)*)
Run Code Online (Sandbox Code Playgroud)

现在:这个正则表达式正在运行,但不是我想要的方式.只有当网址有效时我才需要匹配.

顺便说一句,我认为我还没有完全理解新正则表达式正在做什么:为什么负面前瞻停留在之前.而不是之后呢? 所以我尝试在它之后移动它.,似乎它匹配url,直到它在第二个http之前找到倒数第二个字符.回到正确的正则表达式,我的假设是负面的前瞻实际上是试图检查.正则表达式已经读过之后的内容,这是对的吗?

其他解决方案已被广泛接受,但我首先更愿意理解这一点.谢谢.

Wik*_*żew 2

您寻求的解决方案是

(?>https?://\S+?/(?:(?!https?://).)*)(?!https?://)
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示

细节

  • (?>https?://\S+?/(?:(?!https?://).)*)- 匹配的原子组(不允许回溯到其子模式)
    • https?://-http://或者https://
    • \S+?- 任何 1 个或多个非空白字符,尽可能少,直到第一个...
    • /-/符号后跟...
    • (?:(?!https?://).)*http://- 零个或多个不以或字符序列开头的字符(尽可能多)https://
  • (?!https?://)- 如果存在http://https://紧邻当前位置的右侧,则负向前视会使匹配失败。

不起作用,(https?:\/\/.+?)\/(.+?)(?!https?:\/\/)因为.+?模式是惰性匹配的,即它获取找到的第一个字符,然后让后续的子模式匹配。随后的子模式是负的 loolahead,只有在没有http://https://紧邻当前位置右侧的情况下才会使匹配失败。n由于in后面没有该子串http://test.test/notwork.http://test,所以返回以 结尾的匹配项n,匹配成功。如果您不告诉正则表达式引擎匹配更多或最多一些其他分隔符/模式,它就不会匹配。

脾气暴躁的贪婪令牌解决方案已经被讨论了很多。这个答案涵盖了关于在哪里放置前瞻的确切疑问。