【问题标题】:Regular expression to remove repeated slashes that are after a specific word (VBScript/Classic ASP)用于删除特定单词之后的重复斜杠的正则表达式(VBScript/Classic ASP)
【发布时间】:2016-01-14 02:07:52
【问题描述】:

我在这里苦苦挣扎,试图弄清楚如何替换特定单词之后的所有双斜杠。

例子:

<img alt="" src="/pt/webf//2015//47384_1.JPG" height="235" width="378" />
<div>Don't remove this // or this//</div>

我希望上面的字符串看起来像这样:

<img alt="" src="/pt/webf/2015/47384_1.JPG" height="235" width="378" />
<div>Don't remove this // or this//</div>

请注意,img 标记中的双斜杠已被替换为仅一个斜杠,但在 div 标记中未受影响。如果双斜杠出现在单词之后,我只想替换它们:pt

我尝试过这样的事情:

(?=pt)((.*?)\/\/)+ 

然而,据我所知,它的第一个问题是(?=) 不进行模式回溯。也就是说,它只会寻找第一个匹配的模式。第二个问题是它没有按我的预期工作。

https://regex101.com/r/kC4tA5/1

或者我的做法是错误的,因为正则表达式支持在 VBScript/Classic ASP 中并不广泛,我应该尝试分解字符串和进程,而不是尝试在一个正则表达式中完成所有操作? ??

任何帮助将不胜感激。

谢谢。

【问题讨论】:

  • 损坏的 HTML 从何而来?来源可以修复吗?
  • 它是 VBscript 的一部分,它从大量文件中读取某些 HTML 标签的 sn-ps(我没有编写脚本)。我可以更正实际文件,但文件是由用户创建的,所以这可能会一次又一次地弹出,这就是我试图解决用户 ID10T 错误的原因。事实上,可能有多个这样的文件。目前只找到一个。也许我最好使用 VBScript 来分解 sn-p,应用正则表达式,然后将其重新组合在一起,这样说安全吗?
  • 我认为它正在按预期工作,但问题是您只会捕获最后一次迭代,根据“解释”窗格中的注释:Note: A repeated capturing group will only capture the last iteration. Put a capturing group around the repeated group to capture all iterations or use a non-capturing group instead if you're not interested in the data
  • 我也找不到使用单个正则表达式的任何方法。我认为你需要做类似if /pt/ then s/\/{2,}/\//g(伪代码)的事情。
  • 通常不建议在 HTML 上运行正则表达式。正则表达式在技术上无法解析 HTML,痛苦和绝望就在这条路上。通常你会使用解析器来分离 HTML。

标签: regex vbscript asp-classic backslash slash


【解决方案1】:

我将您的问题解释为“删除所有 &lt;img src&gt; 属性中的重复斜杠。”

正如我在 cmets 中所说,使用 HTML 需要一个解析器。 HTML 对于正则表达式来说太复杂了,各种事情都会出错。

幸运的是,有一个可用于 VBScript 的解析器:htmlfile 对象。它从您的 HTML 字符串创建标准 DOM。所以解决方案就和描述的完全一样了:

Function FixHtml(htmlString)
    Dim doc, img, slashes

    Set slashes = New RegExp
    slashes.Pattern = "/+"
    slashes.Global = True

    Set doc = CreateObject("htmlfile")
    doc.Write htmlString

    For Each img In doc.getElementsByTagName("IMG")
        img.src = slashes.Replace(img.src, "/")
        img.src = Replace(Replace(img.src, "about:blank", ""), "about:", "")
    Next

    FixHtml = doc.body.innerHTML
End Function

不幸的是,htmlfile 不是世界上最先进的 HTML 解析器,但请放心,它仍然比任何正则表达式都要好得多。

有两个小问题:

  1. 我在测试中发现,出于某种原因,它坚持在img.src 前面加上about:about:blank。这不应该发生,但确实发生了。 Replace() 调用的第二行去掉了不需要的添加。

  2. .innerHTML 将生成大写的标签名称,因此&lt;img&gt; 在输出中变为&lt;IMG&gt;。 HTML 源代码中无关紧要的换行符也可能会被删除。这是一个小烦恼,我建议你不要沉迷于此。(*)

但也有两大优势:

  1. DOM 使您能够以结构化的方式处理输入。现在,您可以进行任何数量的复杂修复,而这在正则表达式中是不可能做到的。
  2. .innerHTML 的返回值是正常的 HTML。它将修复输入中的任何严重错误,并将其转化为嵌套良好、转义良好且行为良好的东西。

(*) 如果你发现自己对它着迷,你可以利用this blog post 的智慧创建一个函数,用小写版本替换来自.innerHTML 的所有大写标签他们自己。这实际上是您可以使用正则表达式的东西(准确地说是"(&lt;/?[A-Z]+)"),因为我们知道在字符串中的任何位置都不会出现不属于标记的&lt;,因为那是.innerHTML 的保证。虽然这将是一个很好的练习(它向您介绍了 VBScript 具有函数指针这一鲜为人知的事实),但我想说这并不值得。

【讨论】:

  • 这其实相当出色。谢谢你。最困难的部分是它并不总是img。但我想这并没有那么糟糕。只需梳理文件并查找所有适用的标签类型并根据需要修改上面的功能。再次感谢。
  • 您可以使用.getElementsByTagName("*") 获取所有元素。也有iterate the attributes 的方法。看看我刚刚添加的脚注。
  • 感谢您的博文参考。该脚本(同样,不是我的手艺)实际上在每个适用于处理的 sn-p 上使用了lcase VBScript 函数。所以,一切都变成了小写。但总的来说,该博客文章主题可能会很有帮助。再次感谢。
  • 所以你LCase()整个用户无条件输入?好吧,如果没问题,您当然可以简单地 LCase().innerHTML
  • 不客气。此外,真正听“不要在 HTML 上使用正则表达式”的人值得付出努力。
猜你喜欢
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-04
相关资源
最近更新 更多