6

我正在将我们的 MVC3 项目转换为使用 T4MVC。而且我想替换 java-script 包含也可以与 T4MVC 一起使用。所以我需要更换

"~/Scripts/DataTables/TableTools/TableTools.min.js"
"~/Scripts/jquery-ui-1.8.24.min.js"

进入

Scripts.DataTables.TableTools.TableTools_min_js
Scripts.jquery_ui_1_8_24_min_js

我目前正在使用 Notepad++ 作为正则表达式工具,它正在使用 POSIX 正则表达式。我可以找到脚本名称并将其替换为这些正则表达式:

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

用。。。来代替\(Scripts.\1\)

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

我可以用这个检查 js-filename 的名称中是否有点或破折号

 \("~/Scripts/(?=\.*)(?=\-*).*"\)

但是如何替换组内的组?

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

这是一个非关键问题,我已经手动完成了所有替换,但我认为我对正则表达式很好,所以这个问题困扰着我!!

ps 首选工具是 Notepad++,但任何 POSIX 正则表达式解决方案都可以 -)

pps这里你可以得到一个要替换的东西 的样本这里是目标文本

4

4 回答 4

3

这是一个普通的 Notepad++ 解决方案,但它肯定不是最优雅的解决方案。我设法通过对文件的几次传递来进行转换。

第一关

替换.和。-__

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

用。。。来代替:\1_

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

第二遍

替换/.

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

用。。。来代替:\1.

这与第一遍基本相同,只是字符不同(对于示例文件,您必须这样做 3 次)。按此顺序进行传递可确保没有斜线最终成为下划线。

第三关

删除周围的字符。

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

用。。。来代替:\1

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

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

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

于 2012-10-10T21:28:38.427 回答
3

如果如您的问题所示,您想使用 N++,请使用 N++ Python 脚本。设置脚本并分配一个快捷键,然后您就拥有一个只需要打开、修改和保存的单通道解决方案......没有比这更简单的了。

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

[脚本编辑]:: 更改以匹配修改后的输入/输出预期。

# 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. 安装:: 插件 -> 插件管理器 -> Python 脚本
  2. 新脚本:: 插件 -> Python 脚本 -> script-name.py
  3. 选择目标选项卡。
  4. 运行:: 插件 -> Python 脚本 -> 脚本 -> 脚本名称

[编辑:一个扩展的单行 PythonScript 命令]

由于需要 Python 的新 regex 模块(我希望替换 re),我尝试并编译了它以与 N++ PythonScript 插件一起使用,并决定在您的示例集上对其进行测试。

控制台上的两个命令最终在编辑器中得到了正确的结果。

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 中即可。

其简写为::

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 将完整的缓冲区内容设置为编译的正则表达式替换命令的结果,方法是基本上使用非空组名称的“开关”。

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

于 2012-10-10T23:24:34.057 回答
3

我只会使用像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 步会用 a替换/in ,从而破坏. 我还必须更改第 5 步的代码以说明更改的开头"~/Scripts."~/Script

于 2012-10-11T00:23:04.613 回答
2

或者,您可以使用一个脚本来完成它,并完全避免复制粘贴和其余的手工劳动。考虑使用以下脚本:

$_.gsub!(%r{(?:"~/)?Scripts/([a-z0-9./-]+)"?}i) do |i| 
    'Scripts.' + $1.split('/').map { |i| i.gsub(/[.-]/, '_') }.join('.')
end

并像这样运行它:

$ ruby -pi.bak script.rb *.ext

所有带有扩展名的文件.ext都将被就地编辑,原始文件将以.ext.bak扩展名保存。如果您使用修订控制(并且您应该),那么您可以使用一些视觉差异工具轻松查看更改,必要时更正它们并在之后提交它们。

于 2012-10-12T14:30:14.790 回答