【问题标题】:Javascript Regex to urlify text用于 urlify 文本的 Javascript 正则表达式
【发布时间】:2013-06-18 20:26:29
【问题描述】:

在包含大量以下 url 标记的字符串中 -

[http://www.someurl.com/path/to/resource/?some=params&crazy_chars=true_0_1_0_1]

我想要捕获并转换成的

<a href="http://www.someurl.com/path/to/resource/?some=params&crazy_chars=true_0_1_0_1" target="_blank" class="exturl">http://www.someurl.com/path/to/resource/?some=params&crazy_chars=true_0_1_0_1</a>

因此,方括号内的所有 url 都将被搜索并替换为元素的内联 url。当前我发现 URL 模式的正则表达式为 -

RegExp("\[(http|ftp|https)://[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:/~+#-]*[\w@?^=%&amp;/~+#-])?\]", "gi");

但我仍然不清楚如何在单程中做到这一点。我必须循环直到找不到匹配器吗?

【问题讨论】:

  • 方括号中会不会有不是url的文字?
  • 是的,方括号中还有其他不是URL的文本,例如[@ID:2492395]
  • http://example.iana.org/] 是一个有效的 URL。 http://example.iana.org/[foo] 也是如此
  • 哦,我不知道 URL 可以将 [] 作为有效字符。对于这个问题,假设 URL 没有 []。
  • 它是一个大字符串/文本,其中包含 [] 中的所有这三个变体并且任意次数。

标签: javascript regex text


【解决方案1】:

当前我找到了 URL 模式的正则表达式

但它的目的是作为正则表达式文字,而不是 RegExp 构造函数的字符串参数。您所有的反斜杠都会对以下字符进行字符串转义,并且在正则表达式中无效。相反,使用

/\[(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?\]/gi

但我仍然不清楚如何在单程中做到这一点。我必须循环直到找不到匹配器吗?

不,一个简单的replace call 就足够了。您可以在 url 周围(方括号之间)放置一个 capturing group,然后在替换字符串中使用捕获:

var regex = /\[((?:ftp|http)s?:\/\/[\w-]+(?:\.[\w-]+)+(?:[\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?)\]/gi;
// here:       ^                                                                                       ^
// (the non-capturing groups are optional)
urlified = text.replace(regex, '<a href="$1" class="exturl">$1</a>');
// here:                                 ^^                 ^^

对于更高级的替换规则,您可以使用replace的回调函数参数。

当然,您可能(应该)采用其他答案建议的正则表达式改进/简化。

【讨论】:

    【解决方案2】:

    JavaScript 的正则表达式与 Java 的不太一样。

    JTexy project(类似于 MarkDown,但更好) 有很多用于各种任务的正则表达式,包括 URL matching.

     #(?<=^|[\\s(\\[<:\\x17])(?:https?://|www\\.|ftp://)[0-9.$TEXY_CHAR-][/\\d$TEXY_CHAR+\\.~%&?@=_:;\\#,\\xAD-]+[/\\d$TEXY_CHAR+~%?@=_\\#]#u
    

    $TEXY_CHAR 在项目中的某处定义。

    顺便说一句,使用方括号括住 URL 并不是一个好主意,例如 PHP 使用 [...] 来初始化哈希值,通常用于复选框。

    【讨论】:

      【解决方案3】:

      假设:

      • 没有递归 [[]]
      • 没有空的 []
      • 网址从不包含括号,符号也不尖
      • 只有 [url]、[@ID342892904]、[#sometag] 包含括号

      那么这个简单的正则表达式就可以解决问题:

      \[[^@#]+\]
      
      • \[ 匹配左括号(符号需要转义)
      • [^@#]+ 匹配除 @ 和 # 之外的任何字符,重复 1 次或多次
      • \] 匹配右括号(符号需要转义)

      【讨论】:

        【解决方案4】:

        我会编写一个辅助函数,它将单个 url 字符串作为输入,并在匹配时返回带有该 url 的锚标记。将大字符串解析为一个数组,其中每个元素匹配对应的[] 对。然后只需遍历这个数组并将其传递给辅助函数即可:

        function urlify(s)
        {
          var urlpat = /\[((https?|ftp):\/\/\w+[^\]]*)\]/i;
        
          var matches = urlpat.exec(s);
          var anchor_url = '<a href="%1">%1</a>';
          return matches ? anchor_url.replace(/%1/g, matches[1]) : '';
        }
        
        instring = '[http://www.someurl.com/path/to/resource/?some=params&crazy_chars=true_0_1_0_1]' +
                   '[@ID 65421]' +
                   '[http://google.com]';
        
        var arr = instring.match( /(\[[^\]]+\])/g );
        for(var each in arr)
        {
          arr[each] = urlify(arr[each]);
        }
        

        arr 将包含:

        [ '<a href="http://www.someurl.com/path/to/resource/some=params&crazy_chars=true_0_1_0_1">http://www.someurl.com/path/to/resource/?some=params&crazy_chars=true_0_1_0_1</a>',
          '',
          '<a href="http://google.com">http://google.com</a>' ]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-23
          • 1970-01-01
          • 2013-10-05
          • 1970-01-01
          • 1970-01-01
          • 2020-03-23
          • 2010-09-07
          • 2012-06-23
          相关资源
          最近更新 更多