1

我正在使用XML 正则表达式模式来匹配我的代理 URL。

例如:代理:ab-proxy-sample.company.com:8080

我的要求:

  1. 不应以http://https://开头(匹配整个单词)
  2. 应该接受任何字符串 + 一个端口
  3. 应该接受以ht开头的偶数字符串

我当前的 XML 正则表达式是: [^http://|https://].+:[0-9]+|

但它匹配每个字母而不是整个单词?

任何帮助将不胜感激。提前致谢 !

4

2 回答 2

1

正如@arnep 指出的那样,您正在尝试使用带有替代的否定字符类,这不是它的工作方式。此外,这里有一些关于前瞻的信息。

我相信其他人会发布一个您可以复制和粘贴的答案,但这是学习正则表达式基础知识的有用机会!

更新:

我没有意识到您使用的引擎不支持负面环视。如果没有消极的环顾四周,几乎不可能实现您想要做的事情。

几乎;)

这是一种“蛮力”组合方法:

(?:[^h]|h(?:[^t]|t(?:[^t]|t(?:[^p]|p(?:[^s:]|s(?:[^:]|:(?:[^\/]|\/(?:[^\/])))|:(?:[^\/]|\/(?:[^\/])))))))\S+:\d+
  1. 如果 XML 引擎不支持非捕获组,即(?: ... )使用常规组代替:

    ([^h]|h([^t]|t([^t]|t([^p]|p([^s:]|s([^:]|:([^\/]|\/([^\/])))|:([^\/]|\/([^\/])))))))\S+:\d+
    
  2. 如果 XML 引擎不支持字符类\S\d然后使用[^ \t\r\n\p]and[0-9]代替。

这是一个运行示例:http ://rubular.com/r/JnpCVgeLmL 。尝试更改测试字符串。你会看到...

    ab-proxy-sample.company.com:8080          # matches
    htab-proxy-sample.company.com:8080        # matches
    http://ab-proxy-sample.company.com:8080   # doesn't
    https://ab-proxy-sample.company.com:8080  # doesn't
    httpd://ab-proxy-sample.company.com:8080  # matches

请注意,您不需要^and$。我专门为 Rubular 演示添加了这些,但显然 XML 引擎假定了这种情况(锚定性)。

这是如何运作的?如果我们像这样分解它更容易理解:

    ([^h] | h
    ([^t] | t
    ([^t] | t
    ([^p] | p
    ([^s:]| s ([^:]|:([^\/]|\/([^\/])))
          | :        ([^\/]|\/([^\/])))
    ))))
    \S+:\d+

说明:

  1. 如果第一个字符不是“h”,那就太好了!(字符串不可能是“http://”或“https://”。)
  2. 如果第一个字符“h”,那么:
    1. 如果第二个字符不是“t”,那就太好了!(字符串不可能是“http://”或“https://”。)
    2. 如果第二个字符“t”,那么:
      1. ......不是“t”,太棒了!
      2. ...“t”,那么:
        1. ...不是“p”,太好了!
        2. ...“p”,那么:

在这里,它变得棘手:现在我们遇到三个分支。

  1. 如果第五个字符既不是“s”也不是“:”,那就太好了!
  2. 如果第五个字符“s”,那么:
    1. 如果第六个字符不是“:”,那就太好了!
    2. 如果第六个字符“:”,那么:
      1. 如果第七个字符不是“/”,那就太好了!
      2. 如果第七个字符“/”,那么:
        1. 如果第八个字符不是“/”,那就太好了!
        2. 否则,失败!我们找到了一个“https://”。
  3. 如果第五个字符“:”,那么:
    1. 如果第六个字符不是“/”,那就太好了!
    2. 如果第六个字符“/”,那么:
      1. 如果第七个字符不是“/”,那就太好了!
      2. 否则,失败!我们找到了一个“http://”。

最后,如果我们已经走到这一步,那么我们会寻找一串非空白字符,后跟一个冒号,然后是一串数字。

我把它留给比我自己更聪明的数学家来思考是否所有使用环视匹配的字符串都可以以这种方式“强制”。

于 2012-06-22T14:34:36.640 回答
0

为避免匹配以某个单词开头的字符串,请使用否定前瞻:

^(?!https?).*$

将匹配任何不以 http(s) 开头的字符串。其他要求留给读者作为练习:-)

于 2012-06-25T08:34:24.230 回答