使用正则表达式替换多行文本

Using a Regex to Replace Text Across Multiple Lines

我的 gwt 项目中有一些 css 文件需要更新。我需要找出一个正则表达式,我可以使用它来定位和替换模板表达式 ('%sometext%'),同时还在每个块之前附加一些基于模板的前缀文本。例如,假设我有一大块 css,如下所示:

.x-tabs-wrap, .x-layout-panel .x-tabs-top .x-tabs-wrap {
    background: #deecfd;
    border: 1px solid #8db2e3;
    padding-bottom: 2px;
    padding-top: 0;
}

.x-tabs-strip-wrap{
    padding-top: 1px;
    background: url('%aerotabStripBggif%') #cedff5 repeat-x bottom;
    border-bottom: 1px solid #8db2e3;
}

.x-tabs-strip .x-tabs-text {
    color: #15428b;
    font: bold 11px tahoma,arial,verdana,sans-serif;
}

.x-tabs-strip .on .x-tabs-text {
    cursor: default;
    color: #15428b;
}

.x-tabs-top .x-tabs-strip .on .x-tabs-right {
    background: url('%aerotabSpritegif%') no-repeat right 0;
}

正则表达式应匹配第二个和第五个块并捕获

  1. 从点到右大括号的整个块
  2. 开场模板文字url('%
  3. 模板字符串aerotabSpritegif
  4. 结束模板文本%')

所以最终的预期结果是:

.x-tabs-wrap, .x-layout-panel .x-tabs-top .x-tabs-wrap {
    background: #deecfd;
    border: 1px solid #8db2e3;
    padding-bottom: 2px;
    padding-top: 0;
}

@url aerotabStripBggif aerotabStripBggif;
.x-tabs-strip-wrap{
    padding-top: 1px;
    background: aerotabStripBggif #cedff5 repeat-x bottom;
    border-bottom: 1px solid #8db2e3;
}

.x-tabs-strip .x-tabs-text {
    color: #15428b;
    font: bold 11px tahoma,arial,verdana,sans-serif;
}

.x-tabs-strip .on .x-tabs-text {
    cursor: default;
    color: #15428b;
}

@url aerotabSpritegif aerotabSpritegif;
.x-tabs-top .x-tabs-strip .on .x-tabs-right {
    background: aerotabSpritegif no-repeat right 0;
}

我尝试了多种不同的方法,但到目前为止我找不到任何正确匹配的方法。一切要么太窄,什么都不匹配,要么太宽,最终匹配多个块。到目前为止我能想到的最好的是:

(?s)^\.[A-Za-z]+?.+?url\(\'\%.+?\%\'\).+?\} 

查看 regex101 上的工具,我可以看到在第一个文本块中找不到 url 的匹配项,因此匹配器会一直运行,直到它最终在第二个块中找到匹配项。我需要以某种方式定义开始点和结束大括号是边界,但我似乎无法弄清楚该怎么做。

我在这里做错了什么?我需要做什么才能使此正则表达式按预期运行?

请您尝试搜索模式:

(?m)^(\.[^}]+?)url\('%(.+?)%'\)([^}]+})

和替换:

@url  ;\n

Demo

  • 多行模式 (?m) 使插入符 ^ 匹配任何行的开头。
  • 如您所见,正则表达式 .+?url 尝试跨块匹配 即使您已将 ? 设置为禁用 greedy match。 这是因为点 . 匹配任何内容而不管边界。 然后我将其修改为 [^}]+?url 不超出块。