javascript - 尝试使 IRC 机器人的 URL-Matching RegEx 更快

标签 javascript regex url bots irc

各位程序员,好久不见xD

所以我在 Node.js 上编写了这个 IRC 机器人,主要功能之一是自动超时发布链接而没有权限的用户。

经过大量测试和研究,我想出了这个几乎可以匹配任何 URL 的正则表达式,考虑到用户经常会试图绕过机器人在未经许可的情况下发布链接。

/((?!\w+\.+\s\w+\b)\w+\W*(\.|dot|d0t)\W*(aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|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|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|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|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|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)\b)/i

它考虑到用户在点之间添加空格、用“点”替换点或在点之间添加特殊字符,同时在用户输入“word。很好”之类的内容时忽略匹配项(因为它是一个有效的 url 扩展名)。

这个正则表达式几乎可以处理任何用户试图绕过 url 保护的情况,同时几乎不匹配误报,但我担心它可能会有点慢。

有谁知道一个更好的正则表达式,它具有运行更快的相同功能,或者可能知道如何改进这个运行得更快?

正则表达式解释:

完整的正则表达式:
/((?!\w+\.+\s\w+\b)\w+\W*(\.|dot|d0t)\W*(aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|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|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|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|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|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)\b)/i

团体:(?!\w+\.+\s\w+) - 否定前瞻 - 检查用户是否键入了一个单词 (\w+),后跟一个点或多个点 (.+) 和一个空格 (\s),如果是,则检查下一个字符是否是单词 (\w+)。如果这个正则表达式组匹配,那么用户很可能以句号或省略号结束一个句子,然后是另一个句子,因此正则表达式不应该匹配,即使第二个句子以可能的 url 扩展名开头,例如“is”或“所以”,因此负前瞻应该停止 url 匹配。
\w+ - 一个词 - 这是 url 的第一部分,考虑到 google.com 之类的 url(这将忽略 url 协议(protocol),如果存在的话,以及 url 的第一部分,通常是 www,因为我们的目标只是检测 url,而不是为了其他目的而实际提取它们)。
\W*(\.|dot|d0t)\W* - 任意数量的非字母数字字符后跟一个点(或绕过点的方法),然后是任意数量的非字母数字字符 - 这可以防止用户通过键入诸如 google(dot)com 之类的 url 以及间距来绕过过滤器在 url 单词和点之间,例如 google 。 com。
(aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|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|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|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|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|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) - 匹配任何可能的 url 域扩展 - 这里没什么好说的,这可以防止用户误报使用奇怪的标点符号,例如“短语。下一个短语”
\b - 边界匹配(边界字符或字符串结尾)

编辑:我已经从 (ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au...) 做出了明显的改进至(a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnorsuvxyz]|d[dejkmoz]|e[ceghrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnorstuvxyz]|t[cdfghjklmnoprtvwz]|u[agksyz]|v[aceginu]|w[fs]|y[etu]|z[amw])有没有人知道更多的改进,或者更好的方法来做到这一点?

提前致谢,
加布里埃尔。

最佳答案

可能更快:

domainExtTable = { aero: true, asia: true, biz: true, ... }; // init just once
results = text.match(/((?!\w+\.+\s\w+\b)\w+\W*(\.|dot|d0t)\W*(\w{2,4})\b)/i);
domainExt = results[4];
if (domainExt in domainExtTable) { ... } // this is a match

很难说,取决于正则表达式编译器的好坏。

删除前瞻可能会加快速度。可以肯定的是,您不想匹配“google.com”?

关于javascript - 尝试使 IRC 机器人的 URL-Matching RegEx 更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19424853/

相关文章:

javascript - 使用javascript/html5即时生成声音

javascript - 如何在 React 中动态读取通过 Netlify CMS 创建的 Markdown 文件的特定部分?

javascript - 如何使用 jquery 调用抓取 iframe 内按钮的值?

Javascript 正则表达式 - 当没有尾随空格时如何匹配

ruby-on-rails - Rails 中城市/地区/国家的 URL

javascript - 谷歌地图标签

javascript - 如何在 Javascript 中完全从字符串中删除 URL?

java - 如何从另一个字符串中获取与正则表达式匹配的子字符串?

iOS:从 UITextView 中提取检测到的数字和链接?

Java : access project directory outside src