【问题标题】:Javascript - Replace all phone numbers not already in links to 'click to call' links [duplicate]Javascript - 将链接中尚未包含的所有电话号码替换为“点击通话”链接[重复]
【发布时间】:2015-12-22 00:09:56
【问题描述】:

这是参考我上周发布的question

我想查找页面上的所有有效电话号码。如果它们不在链接中,我想创建一个“点击通话”链接以在移动浏览器上使用。 我收到了关于我发布的原始问题的几个很好的答案,但想尝试不同的方法/扩展反馈。

我正在使用 jQuery 和 Regex 过滤页面内容并使链接可点击。

这是我想出的:

    var phoneRegex = new RegExp(/([(]?\d{3}[)]?[(\s)?.-]\d{3}[\s.-]\d{4})(?![^<]*>|[^<>]*<\/)/g);
    var phoneNums = $( "body *" ).filter(function() {
    var tagname = $(this).prop("tagName");
    tagname = tagname === null ? "" : tagname.toLowerCase(); 
    if (tagname == "a") { 
        return false;
    }
    var match = $(this).html().match(phoneRegex);
    if (match === null || match.length === 0) {
        return false;
    }
    return true;
});
phoneNums.html(function() {
    var newhtml = $(this).html().replace(phoneRegex, function(match) {
        var phonenumber = match.replace(/ /g, "").replace(/-/g, "").replace(/\(/g, "").replace(/\)/g, "");
        var link = '<a href="tel:' + phonenumber + '">' + match + '</a>';
        return link;
    });
    return newhtml;
});

所以,基本上我会搜索正文中的所有内容以查找每个标签(不包括锚标签)。我正在匹配正则表达式并将值存储在“phoneNums”变量中。 从那里我删除所有空格、破折号和括号,以便数字将正确格式化为 tel 属性。 所以像这样的数字:(123) 456-7890 的格式如下:&lt;a href="tel:1234567890"&gt;(123) 456-7890&lt;/a&gt;

我看到这样做的问题是,如果这些数字在页面上的嵌套标签中,我会多次获得结果。 (如果您在返回链接之前执行 console.log 链接,则可以看到这一点。)结果是正确的,但想知道这是否有意义。

有没有更有效的方法来做到这一点?提前致谢!

【问题讨论】:

  • 这就是我在回答中使用XPath 的原因;它使您可以直接找到文本节点,并处理它们,而无需使用正则表达式解析/修改 HTML。您希望尽可能降低工作量,而不是在 .html 上运行查找和替换(这意味着您要替换大量可能包括 script 标记、元素属性等内容的内容)。
  • @ShadowRanger - 您是否有一个示例说明一旦以该格式找到已格式化的数字,我如何将其重新插入到 DOM 中?我是整个 XPath 解决方案的新手。
  • 一旦找到节点,XPath 就不会真正参与。我已经扩展了我的原始答案,包括显示替换如何执行的代码;应该看看那个并删除这个问题。

标签: javascript regex nested filtering


【解决方案1】:

和以前一样(这是在我更新原始问题以包含执行元素替换的代码后复制粘贴的),Don't use regular expressions to parse HTML。使用 HTML/DOM 解析器获取文本节点(浏览器可以为您过滤掉它,例如删除锚标签和所有太短而无法包含电话号码的文本),您可以直接检查文本。

例如,使用 XPath(有点难看,但支持以大多数其他 DOM 方法不支持的方式直接处理文本节点):

// This query finds all text nodes with at least 12 non-whitespace characters
// who are not direct children of an anchor tag
// Letting XPath apply basic filters dramatically reduces the number of elements
// you need to process (there are tons of short and/or pure whitespace text nodes
// in most DOMs)
var xpr = document.evaluate('descendant-or-self::text()[not(parent::A) and string-length(normalize-space(self::text())) >= 12]',
                            document.body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i=0, len=xpr.snapshotLength; i < len; ++i) {
    var txt = xpr.snapshotItem(i);
    // Splits with grouping to preserve the text split on
    var numbers = txt.data.split(/([(]?\d{3}[)]?[(\s)?.-]\d{3}[\s.-]\d{4})/);
    // split will return at least three items on a hit, prefix, split match, and suffix
    if (numbers.length >= 3) {
        var parent = txt.parentNode; // Save parent before replacing child
        // Replace contents of parent with text before first number
        parent.textContent = numbers[0];

        // Now explicitly create pairs of anchors and following text nodes
        for (var i = 1; i < numbers.length; i += 2) {
            // Operate in pairs; odd index is phone number, even is 
            // text following that phone number
            var anc = document.createElement('a');
            anc.href = 'tel:' + numbers[i].replace(/\D+/g, '');
            anc.textContent = numbers[i];
            parent.appendChild(anc);
            parent.appendChild(document.createTextNode(numbers[i+1]));
        }
        parent.normalize(); // Normalize whitespace after rebuilding
    }
}

为了记录,基本过滤器在大多数页面上都有很多的帮助。例如,在这个页面上,我现在看到的(会因用户、浏览器、浏览器扩展和脚本等而异)没有过滤器,查询'descendant-or-self::text()' 的快照将有 1794 个项目。省略以锚标记为父级的文本,'descendant-or-self::text()[not(parent::A)]' 将其降至 1538,而完整查询验证非空白内容至少为 12 个字符长,将其降至 87 个项目。将正则表达式应用于 87 个项目是一个小改动,性能方面,并且您无需使用不合适的工具解析 HTML。

【讨论】:

    猜你喜欢
    • 2017-04-29
    • 2018-04-08
    • 1970-01-01
    • 2020-10-22
    • 2012-08-11
    • 1970-01-01
    • 2016-06-03
    • 2021-05-29
    • 1970-01-01
    相关资源
    最近更新 更多