仅当正则表达式不以 javascript 中的模式开头时才匹配正则表达式

Only match regex if it doesnt start with a pattern in javascript

本文关键字:正则表达式 开头 模式 javascript      更新时间:2023-09-26

我这里有一个有点奇怪的,我基本上有一大块文本,可能包含也可能不包含指向图像的链接。

所以假设我有一个模式可以很好地提取图像 url,但是一旦找到匹配项,它就会被替换为带有链接作为 src 的元素。现在的问题是文本中可能有多个匹配项,这就是它变得棘手的地方。由于 url 模式现在将与 src 标签 url 匹配,这基本上只会进入无限循环。

那么有没有办法只在正则表达式中匹配,如果它不以 ="|=' 这样的模式开头?

some image http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6

但不是

some image <img src="http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6">

我不确定这是否可能,但如果有可能,有人可以指出我正确的方向吗?在这种情况下,替换本身是不够的,因为匹配的 url 也需要在其他地方使用,因此需要像捕获一样使用它。

我需要考虑的主要场景是:

  • 一个不同文本块中的许多链接
  • 没有任何其他文本的单个链接
  • 包含其他不同文本的单个链接

== 编辑 ==

这是我用来匹配网址的当前正则表达式:

('b(https?|ftp|file):'/'/[-A-Z0-9+&@#'/%?=~_|!:,.;]*(?:png|jpeg|jpg|gif|bmp))

== 编辑 2 ==

只是为了让每个人都明白为什么我不能在这里使用/g 命令是一个解释问题的答案,如果我能像我最初尝试的那样使用这个/g,那么它会让事情变得简单得多。

Javascript 正则表达式再次多次捕获

你正在寻找的是负面的背后看,但Javascript不支持任何类型的后视,所以你要么必须使用回调函数来检查匹配的内容并确保它前面没有'",或者你可以使用以下正则表达式:

(?:^|[^"'])('b(https?|ftp|file):'/'/[-a-zA-Z0-9+&@#'/%?=~_|!:,.;]*(?:png|jpeg|jpg|gif|bmp))

它有一个问题,那就是在成功匹配的情况下,它将捕获另一个字符,即输入中('b(https?|ftp|file)模式之前的字符,但我认为您可以轻松处理这个问题。

正则表达式 101 演示

最后使用 /ig 命令应该可以...g用于全局替换,i用于不区分大小写,这是必要的,因为您只有A-Z而不是a-zA-Z

使用以下香草JS似乎对我有用(请参阅jsfiddle(...

var test="some image http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6 some image http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6 some image http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6";
var re = new RegExp(/('b(https?|ftp|file):'/'/[-A-Z0-9+&@#'/%?=~_|!:,.;]*(?:png|jpeg|jpg|gif|bmp))/ig);
document.getElementById("output").innerHTML = test.replace(re,"<img src='"$1'"/>");

虽然,它确实突出显示的是 URL 的查询字符串部分(?v=6没有被您的 RegEx 拾取(。

对于jQuery,它将是(参见jsfiddle(...

$(document).ready(function(){
  var test="some image http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6 some image http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6 some image http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6";
  var re = new RegExp(/('b(https?|ftp|file):'/'/[-A-Z0-9+&@#'/%?=~_|!:,.;]*(?:png|jpeg|jpg|gif|bmp))/ig);
  $("#output").html(test.replace(re,"<img src='"$1'"/>"));
});

更新

以防万一我在示例中使用相同的图像 URL 的示例无法说服您 - 它也适用于不同的 URL......查看此 JSFIDDLE 更新

var test="http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6 http://cdn.sstatic.net/serverfault/img/sprites.png?v=7";
var re = new RegExp(/('b(https?|ftp|file):'/'/[-A-Z0-9+&@#'/%?=~_|!:,.;]*(?:png|jpeg|jpg|gif|bmp))/ig);
document.getElementById("output").innerHTML = test.replace(re,"<img src='"$1'"/>");

您不能只查看网址前面是否有空格而不是单词边界吗? 似乎有效,尽管您稍后必须删除匹配的空格。

('s(https?|ftp|file):'/'/[-A-Z0-9+&@#'/%?=~_|!:,.;]*(?:png|jpeg|jpg|gif|bmp))

http://rubular.com/r/9wSc0HNWas

编辑:该死的,太慢了:)我仍然会把它留在这里,因为我的正则表达式更短;)

正如Freefaller所说,如果exec不是必须的,你可以使用/g标志一次性找到所有匹配项。

否则:您可以将(="|=')?添加到正则表达式的开头,并检查 $1 是否undefined。 如果未定义,则它不是以="|='模式启动