我想转换以下文字

This is a ![foto](foto.jpeg), here is another ![foto](foto.png)

This is a ![foto](/folder1/foto.jpeg), here is another ![foto](/folder2/foto.png)

换句话说,我想找到括在括号中的所有图像路径(文本采用Markdown语法),并用其他路径替换它们。 包含新路径的字符串由单独的real_path函数返回。

我想在它的块版本中使用String#gsub来做这件事。 目前我的代码如下所示:

re = /!\[.*?\]\((.*?)\)/

rel_content = content.gsub(re) do |path|
    real_path(path)
end

这个正则表达式的问题在于它将匹配![foto](foto.jpeg)而不仅仅是foto.jpeg 我也尝试了其他regexen (?>\\!\\[.*?\\]\\()(.*?)(?>\\))但无济于事。

我目前的解决方法是拆分路径并稍后重新组装。

是否有一个Ruby正则表达式只匹配括号内的路径而不是所有上下文所需的字符?

答案后更新 :这里的主要问题是Ruby的regexen没有办法指定零宽度的lookbehinds。 最通用的解决方案是将前面的regexp部分和实际匹配部分之后的部分分组,即/(pre)(matching-part)(post)/ ,然后重建完整的字符串。

在这种情况下,解决方案将是

re = /(!\[.*?\]\()(.*?)(\))/

rel_content = content.gsub(re) do
    $1 + real_path($2) + $3
end

===============>>#1 票数:6 已采纳

快速解决方案(根据需要进行调整):

s = 'This is a ![foto](foto.jpeg)'

s.sub!(/!(\[.*?\])\((.*?)\)/, '\1(/folder1/\2)' )

p s  # This is a [foto](/folder1/foto.jpeg)

===============>>#2 票数:4

您始终可以分两步完成 - 首先提取整个图像表达式,然后再替换链接:

str = "This is a ![foto](foto.jpeg), here is another ![foto](foto.png)"

str.gsub(/\!\[[^\]]*\]\(([^)]*)\)/) do |image|
  image.gsub(/(?<=\()(.*)(?=\))/) do |link|
    "/a/new/path/" + link
  end
end

#=> "This is a ![foto](/a/new/path/foto.jpeg), here is another ![foto](/a/new/path/foto.png)"

我改变了第一个正则表达式,但你可以使用你之前使用的相同的正则表达式。 image是图像表达式![foto](foto.jpeg)link就像foto.jpeg这样的路径。

[编辑]澄清:Ruby确实有lookbehinds(他们在我的答案中使用):

您可以使用(?<=regex)为正数创建lookbehinds ,为(?<!regex)负数,其中regex是受以下条件限制的任意正则表达式。 由于正则表达式实现的限制,外观中的正则表达式必须是固定宽度,这意味着它们不能包含具有未知重复次数的表达式或具有不同宽度选择的替换。 如果你试图这样做,你会收到一个错误。 (但限制不适用于前瞻)。

在您的情况下, [foto]部分具有可变宽度( foto可以是任何字符串),因此由于上述原因,它不能进入​​lookbehind。 然而,lookbehind正是我们所需要的,因为它是零宽度匹配,我们在第二个正则表达式中利用它,只需要担心(固定长度)强制打开括号。

显然你可以从这里real_path ,但我只想要一个可测试的例子。

我认为这种方法比通过匹配组变量重建字符串更灵活,更易读

===============>>#3 票数:3

在您的块中,使用$1访问第一个捕获组(第二个捕获组$2 ,依此类推)。

从文档:

在块形式中,当前匹配字符串作为参数传入,并且将适当地设置诸如$ 1,$ 2,$`,$&和$'的变量。 块返回的值将替换每次调用的匹配。

===============>>#4 票数:1

作为旁注 ,有些人认为“\\ 1”不适合未经证实的字符匹配的情况。 例如,如果要匹配和修改中间内容,如何保护双方角色?

这很简单。 把支架放在其他东西周围。

例如,我希望将a-ruby-porgramming-book-531070.pnga-ruby-porgramming-book.png 删除最后一个“ - ”和最后一个“。”之间的上下文。

我可以使用/.*(-.*?)\\./ match -531070 现在我该如何更换它? 注意其他一切都没有明确的格式。

答案是将括号括在其他东西上,然后保护它们:

"a-ruby-porgramming-book-531070.png".sub(/(.*)(-.*?)\./, '\1.') 
# => "a-ruby-porgramming-book.png"

如果要在匹配的内容之前添加内容,可以使用:

"a-ruby-porgramming-book-531070.png".sub(/(.*)(-.*?)\./, '\1-2019\2.')
# => "a-ruby-porgramming-book-2019-531070.png"

  ask by gioele translate from so

未解决问题?本站智能推荐:

1回复

正则表达式在行首匹配字符串分组

我有一个markdown字符串,像这样: 现在,我想匹配并替换所有标题标签以向其添加另一个标签。 但是我需要避免在文本行中匹配主题标签(Twitter主题标签)。 我正在尝试实现以下字符串: 到目前为止,我已经有了这个正则表达式,它不仅可以完成工作,而且还与twitter标签
1回复

使用python正则表达式转义无效的markdown

我一直试图写一些python来逃避'无效'降价字符串。 这适用于python库(python-telegram-bot),它需要使用\\来转义未使用的降价字符。 我的目标是匹配单独的* , _ , `字符,以及无效的超链接 - 例如,如果没有提供链接,并逃避它们。 我正在寻找的
2回复

正则表达式仅替换部分匹配

香港专业教育学院看过一些类似的话题,但无法找到我正在寻找什么,所以我问一个新问题。 是否可以仅替换与RegEx匹配的字符串的一部分? 例如 我想将00NN替换为+NN 。 不能对00到+进行简单替换。 在RegEx下方,找到2个零和1-9之间的2个后续数字。 这
2回复

将github风格的markdown正则表达式从ruby转换为python

我正在尝试实现在python中工作的github风格markdown的实现,但没有运气...我的正则表达式技能没有太多帮助。 这是来自github的ruby代码: 到目前为止,这是我在python 2.5中提出的内容: 似乎根本没有任何作用:-/ 如果有人能用 pyt
2回复

Ruby正则表达式将星号/下划线表示为强/ em?

作为我正在编写的聊天应用程序的一部分,我需要使用正则表达式来匹配聊天消息中的星号和下划线,并将它们转换为<strong>和<em>标记。 由于我对正则表达式感到很糟糕,所以我真的被困在这里。 理想情况下,我们将其设置为: 可以将一到三个字(但不能更多)标记为
6回复

Ruby用捕获的正则表达式模式替换字符串

我在将其转换为Ruby时遇到麻烦。 这是一段JavaScript,它完全可以完成我想做的事情: 我尝试了gsub , sub和replace,但是似乎都没有达到我的期望。 以下是我尝试过的事情的示例:
2回复

查找和替换分组主题标签的实例

我有一个markdown字符串,像这样: 我想为每个标题添加一个主题标签,以便当markdown呈现为HTML时,它们全部都呈现为下面的title标签。 我想实现以下字符串: 我尝试用一​​个简单的替换来做到这一点: 但是现在当我去做上面的下一个标签时,它将匹配下面的标
1回复

正则表达式封装全行并将其包围

我可以找到围绕一条线的示例,但没有找到围绕并替换的示例,而Regex有点新。 我正在尝试简化我的降价促销,所以我不需要添加html只是为了使其居中。 使用pandoc时,我显然需要用DIV标签环绕并成像,以使其居中,正确对齐或任何其他方式。 我不想每次都键入它,而是想使用rub
2回复

正则表达式Markdown标头

我正在尝试创建一个检查多个条件的正则(红宝石)表达式。 我使用此正则表达式替换对象的内容。 我的正则表达式快要完成了,除了我在减价方面面临的两个问题。 首先,标题给我带来麻烦。 例如,如果标题中包含“ Hi”,我不想将“ Hello”一词替换为“ Hello”。 文字:嗨
1回复

如何使用正则表达式转换Markdown风格的链接?

我正在尝试编写一个替换markdown样式链接的正则表达式,但它似乎不起作用。 这是我到目前为止: 我究竟做错了什么?