【问题标题】:JavaScript + RegEx Complications- Searching Strings Not Containing SubStringJavaScript + RegEx 并发症 - 搜索不包含子字符串的字符串
【发布时间】:2013-08-14 08:53:28
【问题描述】:

我正在尝试使用正则表达式来搜索一个长字符串,但我在想出一个表达式时遇到了麻烦。我正在尝试通过一些 HTML 搜索一组标签,这些标签以包含某个值的标签开始,并以包含另一个值的不同标签结束。我目前用来尝试的代码如下:

matcher = new RegExp(".*(<[^>]+" + startText + "((?!" + endText + ").)*" + endText + ")", 'g');

data.replace(matcher, "$1");

中间的奇怪(((\\?\\!endText).)*)是从另一个线程借来的,发现here,这似乎描述了我的问题。我面临的问题是表达式与开始标签匹配,但它没有找到结束标签,而是包含其余数据。此外,中间的环顾使表情放慢了很多。关于如何让这个工作的任何建议?

编辑:我知道在 RegEx 中解析 HTML 不是最好的选择(让我觉得很脏),但我正处于时间紧迫的状态,我能想到的任何其他选择都可以花费太长时间。很难说我将要解析的标记到底是什么样子,因为我正在动态创建它。我能做的最好的事情就是说我正在查看一个大型数据表,该数据表是为一系列日期的一系列项目收集的。这两个范围都可以变化,我试图从单行中选择一定范围的日期。 startTextendText 的近似值为\\@\\@ASSET_ID\\@\\@_&lt;YYYY_MM_DD&gt;。这个想法是找到对应于这个单元格范围的代码。 (这个编辑很可能让这变得更加混乱,但我不确定在不解释整个应用程序的情况下我还能提供多少信息)。

编辑:嗯,这是一个愚蠢的问题。显然,我只是忘了在最后一个括号后添加.*。不敢相信我花了这么长时间!感谢那些试图提供帮助的人!

【问题讨论】:

  • 除了大量 cmets 正在使用 Regex 解析 HTML(您不应该这样做 - 它不是常规语言)之外,我们至少需要查看示例数据 - 您要替换什么、开始和结束文本是什么、预期输出、实际输出等。
  • 不要听巨魔的。每个工具都有它的时间和地点。我会看看你的问题并尽力帮助你,给我一分钟。
  • @Suamere: 什么 '巨魔'?询问有关使用 regex 解析 HTML 的帖子获得 lots of (valid) cmets 关于 not 使用 regex 解析 HTML 的原因是因为它是错误的工具为了这份工作,这正是弗兰基给出的理由。并且,崩溃:请将您的解决方案发布为您问题的答案。这样一来,将来可能对其他用户有益(鉴于正则表达式的特殊性,这可能不太可能,但回答问题绝不是坏事)。
  • Every tool has a place,(点击那个)不要落入那些盲目地抛弃使用正则表达式处理 HTML 的巨魔。
  • 不知道为什么您上次的编辑说您在最后一个括号后添加了.*。您的情况显然难以描述,但我仍然建议您查看我的答案以帮助清理您的数据。我很想知道更多关于你在处理什么以及为什么 .* 解决了你的问题。它真的不应该被使用而且非常慢。但如果它有效,请使用它。

标签: javascript regex


【解决方案1】:

首先,为什么开头有.*点星号?如果您有如下文字:

This is my Text

如果你想把“我的文本”拉出来,你可以my\sText。你不必这样做.*

话虽如此,由于您现在要匹配的只是您需要的,因此您不需要围绕“Everything”的主要捕获组。这个:.*(xxx) 是一个巨大的禁忌,几乎总是可以用这个代替:xxx。换句话说,您的正则表达式可以替换为:

<[^>]+xxx((?!zzz).)*zzz

从那里我检查它在做什么。

  1. 您正在寻找 HTML 开头的分隔符 &lt;。你消费它。
  2. 您至少使用了一个不是关闭 HTML 分隔符的字符,但可以使用许多字符。这很重要,因为如果您的标签是 &lt;table border=2&gt;,那么到目前为止,您至少已经消费了 &lt;t,如果不是更多的话。
  3. 您现在正在寻找 StartText。如果那个 StartText 是table,你将永远找不到它,因为你已经使用了t。因此,将 + 替换为 *
  4. 如果以下不是结束文本,但从文档的 VERY END 开始,则正则表达式仍然成功,因为 Asterisk 是贪婪的。我建议通过添加 ? 使其变得懒惰。
  5. 当回溯失败时,它会寻找结束文本并成功收集。

该逻辑的结果:

<[^>]*xxx((?!zzz).)*?zzz

如果您仍然要使用点,这对于新的正则表达式编写者来说是可以的,但不建议经验丰富的人使用,我会这样做:

<[^>]*xxx.*?zzz

所以对于 Javascript,你的代码会说:

matcher = new RegExp("<[^>]*" + startText + ".*?" + endText, 'gi');

我把 IgnoreCase "i" 放在那里很好,但你可能想要也可能不想要。

【讨论】:

  • 您可能想在此处简要解释替换、匹配和搜索语句之间的区别 - 因为我认为这就是 OP 遗漏的内容。
  • 是的,在发布这个之后我注意到他正在做一个可能不正确的替换。我几乎为此编辑了我的答案,除了他没有说替换的目的或在他的问题中根本没有注意到它。所以如果他使用我的答案,他可以说OriginalSource = Regex Result(Paracode)。但我认为他现在已经离开了,因为他找到了.*的答案
猜你喜欢
  • 2013-06-26
  • 2013-11-10
  • 2023-02-02
  • 2022-08-19
  • 1970-01-01
  • 2021-06-12
  • 2011-05-25
  • 2020-05-01
  • 1970-01-01
相关资源
最近更新 更多