整个单词的问号(?)量词

时间:2017-10-02 14:29:07

标签: regex

我有很多链接,如:

  • HTTPS%3A%2F%2Fwww.facebook.com%2F
  • HTTPS%3A%2F%2Fwww.facebook.com%2F%3Futm_source

我需要在(%3F)序列之前捕获文本,并捕获整行,如果该序列没有出现在行中。我想在没有if-else条件的情况下执行整个行。

我在寻找什么 - 是为整个字符序列应用?量词的方法,如下所示:^(.*)[\%3F]?

P.S。我知道,有一种方法可以解决问题,首先将HTML样式的字符转换为单个字符(%2F -> "/" and %3F -> "?"),然后将?量词应用于单个字符,但这不是我想解决这个问题的方式。

1 个答案:

答案 0 :(得分:1)

您可以使用

^(?:(?!%3F).)*

将产生与以下表达式相同的结果:

^.*?(?=%3F|$)

但其中最有效的是他们展开的对手

^[^%]*(?:%(?!3F)[^%]*)*

请参阅regex demo

<强>详情

  • ^ - 字符串开头
  • (?:(?!%3F).)* - (a tempered greedy token)任何字符,但换行符(.),连续出现零次或多次,尽可能多(*),这不会启动%3F字符序列
  • .*?(?=%3F|$) - 除了换行符之外的任何零个或多个字符(.*?),尽可能少,直到但不包括%3F子字符串或直到字符串的结尾( $)。

^[^%]*(?:%(?!3F)[^%]*)*模式遵循unroll-the-loop原则,其中[^%]*匹配除%以外的任何字符,(?:%(?!3F)[^%]*)*匹配0个或更多{{1}个序列除了%之外没有3F,然后是0 +字符。由于前瞻条件仅在%上触发,因此如果字符串没有使用%符号过多(在现实世界中情况不同),性能会好得多。