正则表达式不考虑字符串中的短语

时间:2013-12-14 03:10:24

标签: regex tcl

背景如下:

  • 我正致力于将URL(包含或不包含协议和www)转换为 可点击的链接。
  • 我的正则表达式适用于包含httphttpsftpfilewww以及http/https的某些组合的网址www
  • 我还有正则表达式适用于只有www且没有协议的网址。

但是,我无法弄清楚找不到没有协议且没有服务器名称(www)的URL。

我在(http://gskinner.com/RegExr/

中尝试了以下内容
 ([^www\.|http\:// ][a-zA-Z0-9\.]+)((?:[a-zA-Z0-9]+\.)+)([a-zA-Z]{2,4})([\/a-zA-Z0-9]+)([\?][a-zA-Z0-9]+)?

但这似乎只适用于该网站,而不适用于我的应用程序。任何帮助深表感谢。

2 个答案:

答案 0 :(得分:2)

好吧,你可能不会很喜欢这个答案 - 但是那么也许你会这样?我有一个正则表达式(改编自)似乎在文本中找到了URL。您可以看到演示on regex101.com

实际表达非常长 - 这是因为它有“每个合法TLD(顶级域名)”,这是找到“好”网址的良好开端。这里是

((?:(?:http|ftp|https):\/{2}){0,1}(?:(?:[0-9a-z_-]+\.)+(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mn|mo|mp|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|nom|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ra|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw|arpa)(?::[0-9]+)?(?:(?:\/(?:[~0-9a-zA-Z\#\+\%@\.\/_-]+))?(?:\?[0-9a-zA-Z\+\%@\/&\[\];=_-]+)?)?))

正如你所看到的那样,绝大多数的表达方式都被用来确保顶级域名(TLD)是众多合法的一种(270种替代方案。在我偶然发现http://mathiasbynens.be/demo/url-regex之前,我不知道有多少这种方法。我找到了这个表达的种子。)

我对上面链接中找到的表达式所做的更改 - 大部分时间我只是将所有组(外部组除外)都非捕获,因此只有一个“匹配”。在我发布的示例中,我展示了一个“好的”协议定义(如http://)将包含在捕获中,而“坏”协议定义(如http:/)将被忽略 - 但是以下内容仍将捕获URL。我还表明,在表达式之后添加标点符号(使用;!进行测试)不会使表达式逐步显示:它捕获“直到那一点”而不是超出。

玩它,看看你喜欢它。 “病态”网址相对较差(根据上述链接),并且不适用于阿拉伯语等 - 但我不认为,根据您的问题,这将是一个问题。

一个简短的解释:

(?:(?:http|ftp|https):\/{2}){0,1}  

  (?:http|ftp|https)  - match one of http, ftp, or https - non capturing "OR" group
  :\/{2}              - followed by a colon and exactly two forward slashes
  (?: …){0,1}         - the whole thing zero or one times (so no protocol, or properly formed)

(?:(?:[0-9a-z_-]+\.)+ 
   [0-9a-z_-]+\.      - at least one of the characters in the given range, followed by a period
(?:  )+               - the whole thing one or more times, non-capturing

(?:aero|asia …)       - one of these strings, non-capturing (these are all the valid TLDs)
(?::[0-9]+)?          - zero or one times a colon followed by one or more digits: port specification
                      - this makes sure that www.something.us:8080 is valid

随后的所有其他内容都匹配了所有可以追求的不同内容 - 目录,查询等。

答案 1 :(得分:1)

@Floris - 您的建议运作良好。我编辑了一下,并利用 @ 来检测电子邮件。我还编辑了一个更简单的工作流程(没有TLD) -

((?:(?:http|ftp|https):\/{2}){0,1}(?:(?:[0-9a-z_@-]+\.)+(?:[0-9a-zA-Z]){2,4})(?::[0-9]+)?(?:(?:\/(?:[~0-9a-zA-Z\#\+\%\@\.\/_-]+))?(?:\?[0-9a-zA-Z\+\%@\/&\[\];=_-]+)?)?)

感谢您的帮助。

相关问题