2011-11-19 77 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種替代品是相互排斥的,只有一種可以匹配。因此,(?...)子句中只有一個將匹配,因此只有一個將插入文本。