首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Regexp-replace:一个匹配中的多个替换

Regexp-replace:一个匹配中的多个替换
EN

Stack Overflow用户
提问于 2012-10-08 20:00:32
回答 4查看 6.2K关注 0票数 6

我正在将我们的MVC3项目转换为使用T4MVC。我也想替换java-script includes来与T4MVC一起工作。所以我需要替换掉

代码语言:javascript
复制
"~/Scripts/DataTables/TableTools/TableTools.min.js"
"~/Scripts/jquery-ui-1.8.24.min.js"

转到

代码语言:javascript
复制
Scripts.DataTables.TableTools.TableTools_min_js
Scripts.jquery_ui_1_8_24_min_js

我现在使用Notepad++作为正则表达式工具,它使用的是POSIX正则表达式。我可以找到脚本名称并将其替换为以下regexp:

查找:\("~/Scripts/(.*)"\)

替换为\(Scripts.\1\)

但是我不知道如何将文件名中的点和破折号替换为下划线,并将正斜杠替换为点。

我可以检查js-filename名称中是否有点或破折号,如下所示

代码语言:javascript
复制
 \("~/Scripts/(?=\.*)(?=\-*).*"\)

但是如何替换一个组中的组呢?

需要在组内有非贪婪的替换,并让这些替换按顺序进行,因此正斜杠转换为点后将不会转换为下划线。

这是一个不重要的问题,我已经手动完成了所有的替换,但我认为我很擅长使用regexp,所以这个问题困扰着我!

附注:首选工具是Notepad++,但任何POSIX regexp解决方案都可以-)

附注:要替换的材料的Here you can get a sample And here is the the target text

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-10-11 08:23:05

我只会使用像RegexHero这样的网站

  1. 您可以将代码放入目标字符串框,然后将(?<=(~/Script).*)[.-](?=(.*"[)]"))放入Regular Expression框,将_放入Replacement String框。
  2. 替换完成后,单击底部的Final String,然后选择Move to target string and start a new expression。从那里粘贴
  3. ,将(?<=(<script).*)("~/)(?=(.*[)]" ))|(?<=(Url.).*)(")(?=(.*(\)" )))粘贴到Regular Expression框中,并将Replacement String框留空。
  4. 替换完成后,单击底部的Final String,然后选择Move to target string and start a new expression
  5. 从那里将(?<=(Script).*)[/](?=(.*[)]"))粘贴到Regular Expression框中,并将.粘贴到Replacement String框中。

在那之后,Final String盒子就会有你想要的东西。我不确定您可以解析的文本的上限,但如果这是一个问题,它可以被分解。我相信可能会有更好的方法来做这件事,但我倾向于这样做。我喜欢这个网站的一个原因是因为我不需要安装任何东西,所以我可以在任何地方快速安装。

编辑1:根据评论,我已经将步骤3移到了步骤5,并添加了新的步骤3和4。我必须这样做,因为新的步骤5将用.替换"~/Scripts中的/,从而破坏了"~/的删除。我还必须更改步骤5的代码,以说明更改后的Script开头

票数 3
EN

Stack Overflow用户

发布于 2012-10-11 05:28:38

这是一个普通的Notepad++解决方案,但它肯定不是最优雅的解决方案。我设法通过多次遍历文件完成了转换。

第一次通过

.-替换为_

查找:("~/Scripts[^"]*?)[.-]

替换为:\1_

不幸的是,我找不到一种方法来匹配 .-,因为它需要一个后视,而这显然不被Notepad++支持。因此,每次执行替换时,只会替换脚本名中的第一个.- (因为匹配项不能重叠)。因此,您必须多次运行此替换,直到不再执行任何替换为止(在您的示例输入中,将运行8次)。

第二遍

.替换/

查找:("~/Scripts[^"]*?)/

替换为:\1.

这基本上和第一遍是一样的,只是字符不同(对于示例文件,你需要重复3次)。按此顺序进行传递可确保斜杠不会以下划线结尾。

第三遍

删除周围的字符。

查找:"~/(Scripts[^"]*?)"

替换为:\1

这将匹配仍然被"~/"包围的所有脚本名称,捕获中间的内容并将其输出。

请注意,通过在前两遍的查找模式中包含周围的字符,可以避免在已经采用新格式的字符串中转换.

正如我所说的,这不是最方便的方法。特别是,因为第一次和第二次传递必须手动执行多次。但这仍然会为大文件节省大量时间,而且我想不出一种方法,可以在没有后视功能的情况下,在一次遍历中获得所有这些文件-只在正确的字符串中。当然,我非常欢迎改进这个解决方案的建议:)。我希望我至少能给你(和任何有类似问题的人)一个起点。

票数 3
EN

Stack Overflow用户

发布于 2012-10-11 07:24:34

如果,正如您的问题所指出的,您希望使用N++,那么就使用N++ Python脚本。设置脚本并分配快捷键,然后您就有了一个只需要打开、修改和保存的单程解决方案……没有比这更简单的了。

我认为部分问题是N++是而不是正则表达式工具,使用专用的正则表达式工具,甚至是搜索/替换解决方案,有时也是有必要的。使用一个为文本处理而不是编辑的工具,你可能会在速度和时间价值上更好。

修改脚本Edit::以匹配修改后的传入/传出预期。

代码语言:javascript
复制
# Substitute & Replace within matched group.
from Npp import *
import re

def repl(m):
    return "(Scripts." + re.sub( "[-.]", "_", m.group(1) ).replace( "/", "." ) + ")"

editor.pyreplace( '(?:[(].*?Scripts.)(.*?)(?:"?[)])',  repl )

  1. Install::Plugin ->插件管理器-> Python Script
  2. 新建脚本::Plugin -> Python Script ->

目标选项卡。

  1. Run::Plugin -> Python Script ->脚本->脚本名称

Edit:扩展的单行PythonScript命令

由于需要Python的新正则表达式模块(我希望它能取代re),我尝试并编译了它,以便与N++ PythonScript插件一起使用,并决定在您的样例集上测试它。

控制台上的两个命令在编辑器中以正确的结果结束。

代码语言:javascript
复制
import regex as re
editor.setText( (re.compile( r'(?<=.*Content[(].*)((?<omit>["~]+?([~])[/]|["])|(?<toUnderscore>[-.]+)|(?<toDot>[/]+))+(?=.*[)]".*)' ) ).sub(lambda m: {'omit':'','toDot':'.','toUnderscore':'_'}[[ key for key, value in m.groupdict().items() if value != None ][0]], editor.getText() ) )

非常甜蜜!

使用regex而不是re的另一个真正酷的地方是,我能够用Expresso构建表达式,并按原样使用它!只需将r''字符串部分复制粘贴到Expresso中,即可对其进行详细解释。

其缩写文本为::

代码语言:javascript
复制
Match a prefix but exclude it from the capture. [.*Content[(].*]
[1]: A numbered capture group. [(?<omit>["~]+?([~])[/]|["])|(?<toUnderscore>[-.]+)|(?<toDot>[/]+)], one or more repetitions
    Select from 3 alternatives
         [omit]: A named capture group. [["~]+?([~])[/]|["]]
             Select from 2 alternatives
                 ["~]+?([~])[/]
                 Any character in this class: ["]
         [toUnderscore]: A named capture group. [[-.]+]
         [toDot]: A named capture group. [[/]+]
Match a suffix but exclude it from the capture. [.*[)]".*]

命令分解相当巧妙,我们告诉Scintilla将完整的缓冲区内容设置为编译的regex替换命令的结果,实质上是使用不为空的组名的“开关”。

希望Dave ( PythonScript的作者)能将正则表达式模块添加到项目的ExtraPythonLibs部分。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12781312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档