2015-10-23 24 views
1

VB2010:我正在使用RegEx來取消標識文本塊並標準化文本。也就是說,要獲取文本行並取消識別名稱和確認碼,然後對文本進行規範化處理,以便數據以列的形式排列。除了最後一部分,其中的確認代碼前面有可變數量的點以及包長度爲2到4個字符或可能丟失的包ID之外,我幾乎包含了所有內容。Regex.Replace todeidentify/normalize columnar text

'regex 
    Dim MyRegex As Regex = New Regex("(?<pre>^\s{0,2}(\d{1,3})\s(\d\d))(.+?)(?<post>\.\.(\d{1,3})\." + "(\w)\s((\w+?|\.\.)))(?<dots>\.+)(\w{6})", RegexOptions.IgnoreCase Or RegexOptions.Multiline) 

    'this is the replacement string 
    Dim replacement As String = "${pre}******/*****${post}${dots}******" 

    'replace the matched text in the InputText using the replacement pattern 
    Dim result As String = MyRegex.Replace(Input, replacement) 

我的測試輸入與號碼,姓名,號碼,雜項代碼,包ID和確認碼上的每一行:

1 01SMITH/CH..1.A E2T......AAABBB 
    2 01MTC..1.A ..............CCCDDD 
    3 01GRIFFIN/JOHN..1.A E2...EEEFFF 
    4 01EL/MARY..1.Z E2XT......GGGHHH 
    5 02BUBBA/BILLY..2.A E2....IIIJJJ 
    6 01HILL/THOR..1.A E2WW....KKKLLL 

我的輸出到目前爲止:

1 01******/*****..1.A E2T......****** 
    2 01******/*****..1.A ..............****** 
    3 01******/*****..1.A E2...****** 
    4 01******/*****..1.Z E2XT......****** 
    5 02******/*****..2.A E2....****** 
    6 01******/*****..1.A E2WW....****** 

我將取消標識名稱和確認代碼,但在確認代碼是可變的之前代碼包ID纔會丟掉柱狀輸出。它的末端部分卡住了,但我真的很接近。我打算做一個正則表達式,但它可能是不可能的。是否可以填充正則表達式替換?

更新了一個解決方案:

'regex (added one more group for the package id so I can determine its length) 
    Dim MyRegex As Regex = New Regex("(?<pre>^\s{0,2}(\d{1,3})\s(\d\d))(.+?)(?<post>\.\.(\d{1,3})\.(\w)\s(?<pkid>(\w+?|\.\.)))(?<dots>\.+)(\w{6})", RegexOptions.IgnoreCase Or RegexOptions.Multiline) 

    'use the MatchEvaluator to examine each match and adjust accordingly 
    deid = MyRegex.Replace(deid, New MatchEvaluator(Function(m As Match) 
                 Return m.Groups("pre").Value & 
                  "******/*****" & 
                  m.Groups("post").Value & 
                  New String("."c, 5 - m.Groups("pkid").Value.Length) & 
                  "******" 
                End Function)) 

我運行,通過測試數據,這裏是我所得到的:

-----Input------------------------------------------------ 
1 01SMITH/CH..1.A E2T......AAABBB 
2 01MTC..1.A ..............CCCDDD 
3 01GRIFFIN/JOHN..1.A E2...EEEFFF 
4 01EL/MARY..1.Z E2XT......GGGHHH 
5 02BUBBA/BILLY..2.A E2....IIIJJJ 
6 01HILL/THOR..1.A E2WW....KKKLLL 
-----Output----------------------------------------------- 
1 01******/*****..1.A E2T..****** 
2 01******/*****..1.A .....****** 
3 01******/*****..1.A E2...****** 
4 01******/*****..1.Z E2XT.****** 
5 02******/*****..2.A E2...****** 
6 01******/*****..1.A E2WW.****** 
---------------------------------------------------------- 
+0

什麼是你想要的輸出獲得? –

+0

我認爲你知道沒有正則表達式很容易做到嗎? –

+0

stribizhev顯示輸出,但排隊。現在,除了確認碼外,所有東西都排成一列。安德魯我知道我可以做到這一點,沒有正則表達式,但上面的數據是一個更大的文件的一部分,我希望只是替換這部分。 – sinDizzy

回答

1

也許,可以有一個更好的辦法,但有可能用your regexRegex.Replace using a MatchEvaluator來達到你想要的效果。

evaluator
類型:System.Text.RegularExpressions.MatchEvaluator
檢查每個匹配並返回要麼是原始匹配的字符串或替換字符串的定製方法。

重點是獲取組3和組8的長度,並重復*相同的次數。要添加正斜槓,我們可以通過將組3的長度除以2來找到中間值。StrDup是一個方便的函數,它將字符串「倍增」指定的次數。

這裏是一個VB.NET代碼:

Dim Input As String = "1 01SMITH/CH..1.A E2T......AAABBB" & Environment.NewLine & "2 01MTC..1.A ..............CCCDDD" & Environment.NewLine & "3 01GRIFFIN/JOHN..1.A E2...EEEFFF" & Environment.NewLine & "4 01EL/MARY..1.Z E2XT......GGGHHH" & Environment.NewLine & "5 02BUBBA/BILLY..2.A E2....IIIJJJ" & Environment.NewLine & "6 01HILL/THOR..1.A E2WW....KKKLLL" 
Dim MyRegex As Regex = New Regex("(?<pre>^\s{0,2}(\d{1,3})\s(\d\d))(.+?)(?<post>\.\.(\d{1,3})\." + "(\w)\s((\w+?|\.\.)))(?<dots>\.+)(\w{6})", RegexOptions.IgnoreCase Or RegexOptions.Multiline) 
Dim result As String = MyRegex.Replace(Input, New MatchEvaluator(Function(m As Match) 
            Return m.Groups("pre").Value & 
            StrDup(m.Groups(3).Value.Length, "*").Insert(m.Groups(3).Value.Length/2, "/") & 
            m.Groups("post").Value & 
            m.Groups("dots").Value & 
            StrDup(m.Groups(8).Value.Length, "*") 
           End Function)) 
Console.WriteLine(result) 

結果:

1 01****/****..1.A E2T......****** 
2 01**/*..1.A ..............****** 
3 01******/******..1.A E2...****** 
4 01****/***..1.Z E2XT......****** 
5 02******/*****..2.A E2....****** 
6 01****/*****..1.A E2WW....****** 
+0

我相當確定其目的是用固定字符串「******/*****」替換任何名稱,而不是用星號替換字符。 –

+0

安德魯是的,這是我的初衷,但有了這一點的幫助,我認爲這是行得通的。讓我測試一些修改的代碼,並將附加到原始請求。 – sinDizzy

+1

stribizhev感謝您的提示。我不認爲我曾經使用過MatchEvaluator,但肯定會將它添加到我的工具箱中。基於你的建議的最終解決方案,我調整了一下,以調整包ID和確認碼之間的點。這是需要修改的變量,它可以工作。甚至不需要「點」組。最後的代碼在操作。 – sinDizzy