2011-11-19 20 views
4

我有我想用查找操作和在记事本替换++在文本文件中标签名称的列表,它们列出如下:记事本++ RegeEx组捕捉语法

MyLabel_01 
MyLabel_02 
MyLabel_03 
MyLabel_04 
MyLabel_05 
MyLabel_06 

我想将其重命名在记事本++以下几点:

Label_A_One 
Label_A_Two 
Label_A_Three 
Label_B_One 
Label_B_Two 
Label_B_Three 

正则表达式我使用的记事本+ +的替换对话框捕捉标签名称如下:

((MyLabel_0)((1)|(2)|(3)|(4)|(5)|(6))) 

我想如下替换每个捕获组:

\1 = Label_ 
\2 = A_One 
\3 = A_Two 
\4 = A_Three 
\5 = B_One 
\6 = B_Two 
\7 = B_Three 

我的问题是记事本++没有注册上述正则表达式的语法。当我在替换对话框中点击计数时,它返回0次出现。不知道语法中有什么错误。是的,我确定选择了正则表达式单选按钮。帮助表示赞赏。

UPDATE:

试图逃避括号,仍然没有工作:

\(\(MyLabel_0\)\((1\)|\(2\)|\(3\)|\(4\)|\(5\)|\(6\)\)\) 

回答

5

Ed的反应已经显示出工作模式交替,因为没有在记事本++的支持,但是你剩下的问题不能由单独的正则表达式处理。使用正则表达式查找/替换方法,您尝试做的事情是不可能的。您所期望的结果涉及无法用正则表达式表示的逻辑条件。你可以用替换方法做的所有事情都是重新排列项目并引用捕获的项目,但是不能告诉它使用值“1-3”的“A”和4-6的“B”。此外,你不能像这样分配占位符。他们确实是您正在反向参考的捕获组。

为了达到你显示你需要写一个小程序,将允许你检查捕获的值,并进行适当的替代品的结果。

编辑:这里是如何实现这在C#

var numToWordMap = new Dictionary<int, string>(); 
numToWordMap[1] = "A_One"; 
numToWordMap[2] = "A_Two"; 
numToWordMap[3] = "A_Three"; 
numToWordMap[4] = "B_One"; 
numToWordMap[5] = "B_Two"; 
numToWordMap[6] = "B_Three"; 

string pattern = @"\bMyLabel_(\d+)\b"; 
string filePath = @"C:\temp.txt"; 
string[] contents = File.ReadAllLines(filePath); 

for (int i = 0; i < contents.Length; i++) 
{ 
    contents[i] = Regex.Replace(contents[i], pattern, 
     m => 
     { 
      int num = int.Parse(m.Groups[1].Value); 
      if (numToWordMap.ContainsKey(num)) 
      { 
       return "Label_" + numToWordMap[num]; 
      } 
      // key not found, use original value 
      return m.Value; 
     }); 
} 

File.WriteAllLines(filePath, contents); 

你应该能够很容易地使用这样的一个例子。也许你可以下载LINQPadVisual C# Express这样做。

如果您的文件太大,这可能是一种效率低下的方法,在这种情况下,您可以使用StreamReaderStreamWriter分别从原始文件读取并将其写入另一个文件。

另请注意,我的示例代码回写到原始文件。出于测试目的,您可以将该路径更改为另一个文件,以免被覆盖。

+0

谢谢艾哈迈德,无论如何,这可以使用像grep这样的工具来完成吗? – kingrichard2005

+0

@ kingrichard2005我对grep并不太熟悉,对它的快速搜索似乎没有揭示这样的功能。我确实找到了一个名为PowerGREP的工具。它不是免费的,但它们提供了一个试验和[支持额外的处理能力](http://www.powergrep.com/extra.html),它将提供映射替换功能(它们的屏幕截图示例显示了一些被替换的URL编码字符) 。尽管这种类型的功能不太难编码。我已经通过使用C#的示例方法更新了我的帖子,可能会对您有所帮助。 –

+0

谢谢艾哈迈德,我最终手动重命名了标签,幸运的是没有太多。我会接受你的回答,因为我没有意识到只用正则表达式就无法做到这一点。感谢您的建议和示例备选方案。 – kingrichard2005

4

吧吧吧 - 记事本++觉得你是个野蛮人。

(过时 - 见下文更新)中Notepad++ regex没有竖线 - 对不起。我每隔几个月也会忘记!

使用[123456]代替。

更新:对不起,我没有仔细阅读不够;在购物问题之上,@艾哈迈德的发现 - 你不能做这样的映射替换。

更新:Notepad ++第6版将正则表达式引擎更改为支持“|”的Perl兼容正则表达式引擎。 AFAICT,如果你有一个版本5 ,自动更新将不会更新到6 - 你必须明确地下载它。

-2

最简单的方法来做到这一点,我会建议使用AWK。如果你使用的是Windows,那么可以在这里找到免费下载的mingw32预编译的二进制文件(它会被称为gawk)。

BEGIN { 
    FS = "_0"; 
    a[1]="A_One"; 
    a[2]="A_Two"; 
    a[3]="A_Three"; 
    a[4]="B_One"; 
    a[5]="B_Two"; 
    a[6]="B_Three"; 
} 

{ 
    printf("Label_%s\n", a[$2]); 
} 

在Windows上执行如下:

C:\Users\Mydir>gawk -f test.awk awk.in 
Label_A_One 
Label_A_Two 
Label_A_Three 
Label_B_One 
Label_B_Two 
Label_B_Three 
0

正则表达式搜索和替换

MyLabel_((01)|(02)|(03)|(04)|(05)|(06)) 

Label_(?2A_One)(?3A_Two)(?4A_Three)(?5B_One)(?6B_Two)(?7B_Three) 

作品在记事本6.3.2

最外面的一对括号用于分组,它们限制了第一次交替的范围;不确定它们是否可以省略,但包括它们使得范围清晰。该模式搜索一个固定的字符串,然后是两个数字对之一。 (前导零可以被分解并放置在固定字符串中。)每个数字对被包装在圆括号中以便被捕获。

在替换表达式中,子句(?4A_Three)表示如果捕获组4匹配了某些内容,则插入文本A_Three,否则不插入任何内容。对于其他条款也是如此。由于这6种替代品是相互排斥的,只有一种可以匹配。因此,(?...)子句中只有一个将匹配,因此只有一个将插入文本。