【问题标题】:Get all links from html page using regex使用正则表达式从 html 页面获取所有链接
【发布时间】:2016-12-14 06:26:36
【问题描述】:

我正在使用 Google Apps 脚本从 gmail 获取电子邮件的内容,然后我需要从 html 标记中提取所有链接。我在 stackoverflow 上找到了一些代码,并用正则表达式实现了它,但问题是它总是返回第一个 url。 (http://vacante2016.eu/tr/17599/51743713/c4f5eadf38eb475d39e3cdeca9201538)

有没有办法创建一个循环来搜索与正则表达式匹配的下一个内容以逐个显示所有元素?

在这里您可以看到一个示例,其中包含我需要从中获取这些链接的电子邮件内容:https://www.mailinator.com/inbox2.jsp?public_to=get_urls#/#public_showmaildiv

这是我的代码:

function getURL() {

  var threads = GmailApp.getInboxThreads();
  var message = threads[0].getMessages()[0];
  var content = message.getRawContent();

    var source = (content || '').toString();
    var urlArray = [];
    var url;
    var matchArray;

    // Regular expression to find FTP, HTTP(S) URLs.
    var regexToken = /(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/;

    // Iterate through any URLs in the text.
    while( (matchArray = regexToken.exec( source )) !== null )
    {
      var token = matchArray[0];
      urlArray.push( token );
    }
}

更新: 将正则表达式更改为 /(?:ht|f)tps?\:\/\/[a-zA-Z0-9\-.]+\.[a-zA-Z]{2,3}(\/[\S=]*)?/g 改进了这些事情,但现在我在搜索 url 时也得到以下类型的响应:"http://vacante2016.eu/clk/17599/5=\r\n1743713/150132/bf7639dd7e7aa48c9197a52a8c61e168\"><img" ...我认为正则表达式也应该有一个条件来返回 url 但只有直到> 符号。

另外,有没有办法从找到的 url 中删除额外的字符,如 =\r\n

【问题讨论】:

  • 看起来你忘记了/gvar regexToken = /(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/g;。见stackoverflow.com/questions/520611/…
  • 如果电子邮件是 html 格式的,是否有理由说明您为什么不直接从标签中获取属性?
  • @NTL 不,没有理由,但我不知道该怎么做...我认为正则表达式必须从<a> 和@987654337 中搜索href 属性@标签
  • @WiktorStribiżew 修复了它,但现在看起来像这样的 url 响应:http://vacante2016.eu/tr/17599/51743713/c4f5eadf38eb475d39e3cde=ca9201538 将在= 之后被截断,如下所示:http://vacante2016.eu/tr/17599/51743713/c4f5eadf38eb475d39e3cde .. 为什么会发生这种情况?
  • 好吧,/(?:ht|f)tps?\:\/\/[a-zA-Z0-9\-.]+\.[a-zA-Z]{2,3}(\/\S*)?/gshould work。检查您对链接所做的操作或是否检查预期内容。

标签: javascript regex google-apps-script


【解决方案1】:

我假设根据您提供的代码,您能够以 html 字符串的形式获取电子邮件的内容。

function getHref(content){
  var el = document.createElement('html');
  el.innerHTML = content;

  var hrefs = [];

  var elements = el.getElementsByTagName('a');

  for (var i=0; i < elements.length; i++){
    hrefs.push(elements[i].href);
  }

  return hrefs;
}

这将返回页面上锚标记的所有 href 属性的数组。

【讨论】:

  • 在 Google Apps 脚本中无法访问 document 对象。该框架不支持所有的 JS 特性,只支持其中的一部分。
  • 这仅适用于浏览器,客户端。 Google Apps 脚本是服务器端的,根本没有 DOM。
【解决方案2】:

您需要使用全局修饰符/g 来获得与RegExp#exec 的多个匹配项。

此外,由于您的输入是 HTML 代码,因此您需要确保不要使用 \S 抓取 &lt;

/(?:ht|f)tps?:\/\/[-a-zA-Z0-9.]+\.[a-zA-Z]{2,3}(\/[^"<]*)?/g

请参阅regex demo

如果由于某种原因此模式与等号不匹配,请添加它作为替代:

/(?:ht|f)tps?:\/\/[-a-zA-Z0-9.]+\.[a-zA-Z]{2,3}(?:\/(?:[^"<=]|=)*)?/g

another demo(不过,第一个应该可以)。

【讨论】:

  • 第二种模式完美!最后一个问题...有没有办法从找到的网址中删除=\r\n 等附加字符,这样"http://vacante2016.eu/clk/17599/5=\r\n1743713/150132/bf7639dd7e7aa48c9197a52a8c61e168\" 将是"http://vacante2016.eu/clk/17599/51743713/150132/bf7639dd7e7aa48c9197a52a8c61e168\"
  • 我不知道这些是不是文字字符串。如果是,你将不得不使用像.replace(/\\[rn]|=/g, '')这样的东西。
  • 它们是刺痛的文字,我使用 token.replace(/\\[rn]|=/g, '') 并没有任何反应。可以肯定的是,在使用替换之前我也做了 toke.toString()。
  • 那就试试.replace(/[\r\n=]+/g, "")
  • 这部分是因为只删除了=。我也尝试了.replace("\r", "") 并且什么也没做......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-29
  • 2012-05-28
  • 2013-08-28
  • 2021-08-03
  • 1970-01-01
相关资源
最近更新 更多