【问题标题】:How can I search and replace, using regex, within the results of a previous search?如何使用正则表达式在先前搜索的结果中搜索和替换?
【发布时间】:2013-12-07 10:31:58
【问题描述】:

感谢您抽出宝贵的时间阅读本文,如果这有点令人困惑、补救或之前曾被问过(广泛搜索,结果有限),请立即道歉。

我正在使用古老的软件进行编辑,如果您熟悉 HomeSite 5,它允许使用脚本。

我的困惑如下:

我想隔离多个文本选择。我目前正在使用(冗长的)正则表达式来执行此操作,该表达式捕获 certain 特定设置日期(在本例中为“2030-12-31”)之后的所有内容,直到它到达某个标签(在这种情况下]]<content>)。到目前为止,我已经做到了。

然后,我希望仅在那些先前找到的文本选择中删除它包含的所有<span> 标记。但是,我希望保留其他文本部分中的 <span> 标记(例如那些分配较早日期的标记)。

我可以单独执行这两个功能,隔离特定部分或删除所有<span> 标签,我觉得只有一个我不知道的链接可以让我在另一个中运行一个。

再次道歉,如果答案很简单;我对脚本和正则表达式的了解充其量是有限的。我一直在使用 Jscript 完成大部分工作,但我不确定 HomeSite 是否接受其他格式 - 我愿意接受多种解决方案!

TLDR:仅在某些选择中搜索和替换,由紧接在前的正则表达式指定。

编辑 1: 请参阅下面用于隔离所需部分的表达式。第一个是整个表达式。第二个是捕获内容的容器。:

/<version recordId="([0-9]{4,})" start="2030-12-31"([^>]*)>([^<]*)<title><!\[CDATA\[<span class="uk">([^<]*)<\/span>\]\]><\/title>([^<]*)<number><!\[CDATA\[<span class="uk">([0-9]{1,3})\.<\/span>\]\]><\/number>([^<]*)<content><!\[CDATA\[([^]]*)\]\]><\/content>([^<]*)<\/version>/g;

..<content><!\[CDATA\[([^]]*)\]\]></content>..

在此我想修改如下:

<span class="uk">content</span>
content

现在我已经在公共场合输入了它,我知道这是一个正则表达式的恐怖表演,我向 stackoverflow 的优秀编码人员道歉,甚至不得不看它!

编辑 2: 请参阅下面的所需输出示例:

<version recordId="1234" start="2012-01-01"><stuffhere...<content><![CDATA[[
  <span class="uk">content1</span>
  <span class="uk">content2</span>
 ]]</content>
    </version>
 <version record="4231" start="2030-12-31"><stuffhere...<content><![CDATA[[
   <span class="uk">content1</span>
   <span class="uk">content2</span>
 ]]</content>
    </version>

变成

<version recordId="1234" start="2012-01-01"><stuffhere...<content><![CDATA[[
  <span class="uk">content1</span>
  <span class="uk">content2</span>
 ]]</content>
    </version>
 <version record="4231" start="2030-12-31"><stuffhere...<content><![CDATA[[
   content1
   content2
 ]]</content>
    </version>

n.b:感谢 Hannele 早期的格式更正。

【问题讨论】:

  • 您能否提供一些示例输入、所需的输出以及您已有的正则表达式?
  • following a certain date: 正则表达式对于这种工作来说不够强大。您最多可以像您尝试过的那样精确匹配一个日期,但您将无法匹配 youngest 日期。它还能满足您的需求吗?
  • @sp00m,感谢您浏览这个问题。抱歉,如果上面的文字墙完全不清楚:分配给我要编辑的内容的日期将始终是“开始 =“2030-12-31”。我在使用 RegEx 时没有遇到任何问题,尽管时间很长,但可以选择正确的部分。当我只想在这些部分中编辑内容时,麻烦就开始了。日期不同的部分,即 'start="2012-01-01"' 或 'start="1998-29-02"' 将被忽略。再次感谢,伙计。

标签: javascript regex search replace jscript


【解决方案1】:

使用带有String.replace()的回调函数

String.replace() 方法的第二个参数(替换文本)可以指定为回调函数。这个回调函数又可以有另一个replace() 调用。通过这种方式,您可以轻松地处理节内的文本。这是一个演示此技术的示例。

鉴于此示例文本:

之前:

blah foo? foo blah foo, foo.
&lt;section1&gt;blah foo? foo blah foo, foo.&lt;/section1&gt;
blah foo? foo blah foo, foo.
&lt;section2&gt;blah foo? foo blah foo, foo.&lt;/section2&gt;
blah foo? foo blah foo, foo.

假设您想用bar 替换每个foo,但仅限于部分内。这很容易通过使用回调函数作为String.replace() 方法的替换参数来完成,如下所示:

function f1(text) {
    var re1 = /<section(\d+)>[\S\s]*?<\/section\1>/g;
    var re2 = /foo/ig;
    text = text.replace(re1,
        function(m0, m1){
            return m0.replace(re2, 'bar');
        });
    return text;
}

当找到模式匹配时,replace() 方法调用回调函数并在第一个参数中传递整个匹配(在上面的示例中,我将其命名为:"m0")。如果正则表达式具有捕获组,则这些组中的每一个的匹配文本将在以下参数中传递(在这种情况下,只有一个捕获组,我已将此参数命名为:"m1" - 请注意,此参数是未被函数使用)。

这是经过上述函数处理后的示例文本:

之后:

blah foo? foo blah foo, foo.
&lt;section1&gt;blah bar? bar blah bar, bar.&lt;/section1&gt;
blah foo? foo blah foo, foo.
&lt;section2&gt;blah bar? bar blah bar, bar.&lt;/section2&gt;
blah foo? foo blah foo, foo.

【讨论】:

  • 非常感谢@ridgerunner,提供了一个非常优雅的解决方案。简洁而有效,我知道会有一种我不知道的技术,我现在已经将“替换中的函数”带到其他脚本并找到了改进。再次感谢。
猜你喜欢
  • 2022-11-26
  • 1970-01-01
  • 2013-06-14
  • 2013-11-30
  • 1970-01-01
  • 2010-11-19
  • 2018-05-25
  • 2010-11-25
相关资源
最近更新 更多