使用正则表达式替换多行文本
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;
}
正则表达式应匹配第二个和第五个块并捕获
- 从点到右大括号的整个块
- 开场模板文字url('%
- 模板字符串aerotabSpritegif
- 结束模板文本%')
所以最终的预期结果是:
.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
- 多行模式
(?m)
使插入符 ^
匹配任何行的开头。
- 如您所见,正则表达式
.+?url
尝试跨块匹配
即使您已将 ?
设置为禁用 greedy match
。
这是因为点 .
匹配任何内容而不管边界。
然后我将其修改为 [^}]+?url
不超出块。
我的 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;
}
正则表达式应匹配第二个和第五个块并捕获
- 从点到右大括号的整个块
- 开场模板文字url('%
- 模板字符串aerotabSpritegif
- 结束模板文本%')
所以最终的预期结果是:
.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
- 多行模式
(?m)
使插入符^
匹配任何行的开头。 - 如您所见,正则表达式
.+?url
尝试跨块匹配 即使您已将?
设置为禁用greedy match
。 这是因为点.
匹配任何内容而不管边界。 然后我将其修改为[^}]+?url
不超出块。