2016-01-05 25 views
1

嘗試解析某些OpenXML標準(docx)時遇到問題。我們使用如{Contact.MailAddress}這樣的表達式,並在第二步中從數據中填充此表達式。但是,那樣的話(和LibreOffice)是,是,他們有時分頭這些標籤是這樣的:試圖解析XML時的失控回溯

<w:r w:rsidRPr="00E22BCD"> 
    <w:rPr> 
     <w:rFonts w:eastAsia="Times New Roman"/> 
     <w:lang w:val="fr-CH"/> 
    </w:rPr> 
    <w:t>{</w:t> 
</w:r> 
<w:proofErr w:type="spellStart"/> 
<w:r w:rsidRPr="00E22BCD"> 
    <w:rPr> 
     <w:rFonts w:eastAsia="Times New Roman"/> 
     <w:lang w:val="fr-CH"/> 
    </w:rPr> 
    <w:t>Contakt.MailAddress</w:t> 
</w:r> 
<w:proofErr w:type="spellEnd"/> 
<w:r w:rsidRPr="00E22BCD"> 
    <w:rPr> 
     <w:rFonts w:eastAsia="Times New Roman"/> 
     <w:lang w:val="fr-CH"/> 
    </w:rPr> 
    <w:t>}</w:t> 
</w:r> 

所以,我提出以下的正則表達式:

(?<expr>{)((?<tag><[^>]+>)|(?<expr>[\w\s.]+))+(?<expr>}) 

expr組萬事部分{Contact.MailAddress}表達式並被合併在一起。 tag組中的所有內容都會被合併到標籤中,以便稍後將xml修復。

現在,這工作得很好。但是,當我們使用{foreach}語法時,xml可能會變得相當大,然後我們會遇到失控的情況。

任何人都可以想到一個正則表達式,它可以更好地捕獲這個並不會導致失控?

編輯1:該程序是用C#/。NET編寫的。對於正則表達式的味道。

編輯2:我花了另一種方法:我上市,其中有一個匹配的所有比賽一樣{[^}]}並在那裏,我什麼也沒有取代所有的標籤和空格:

var matches = Regex.Matches(xml, @"{[^}]+}") 
    .Cast<Match>() 
    .OrderByDescending(x => x.Index) 
    .ToList(); 

foreach (var match in matches) 
{ 
    var replacement = Regex.Replace(match.Value, @"<[^>]+>", ""); 
    replacement = Regex.Replace(replacement, @"\s+", ""); 
    xml = xml.Substring(0, match.Index) + replacement + xml.Substring(match.Index + match.Length); 
} 

關鍵是要訂購比賽通過索引降低,所以在Substring工作的數學。

+0

http://stackoverflow.com/a/1732454/1030675 – choroba

+0

你的正則表達式的風格是什麼? – Stephan

+0

@Stephan C#/ .NET – LueTm

回答

1

它看起來像你想要刪除{}之間的所有標籤和空格。如果你不擔心,不應該匹配其他括號,這應該工作:

s = Regex.Replace(s, 
    @"(?<brace>{)\s*(?:<[^<>]+>\s*)*|\s*(?:<[^<>]+>\s*)*(?<brace>})", 
    @"${brace}"); 

爲了安全起見,你可能要添加最近的實際標籤(假設他們總是相同):

@"(?<brace>{)</w:t>\s*(?:<[^<>]+>\s*)*|\s*(?:<[^<>]+>\s*)*<w:t>(?<brace>})" 

使用任一正則表達式,我得到這樣的結果:

<w:r w:rsidRPr="00E22BCD"> 
    <w:rPr> 
     <w:rFonts w:eastAsia="Times New Roman"/> 
     <w:lang w:val="fr-CH"/> 
    </w:rPr> 
    <w:t>{Contakt.MailAddress}</w:t> 
</w:r> 

...而且也沒有回溯的。

編輯:

原來的標籤也被前後括號內的點之後插入。我原來的解決方案不會爲工作,所以這裏有一個兩階段的做法,發現括號括起來的文本,並與標籤和空白同一文本中刪除替代它:

s = Regex.Replace(s, 
    @"{[^{}]*}", 
    m => Regex.Replace(m.Value, @"\s*(?:<[^<>]+>\s*)*", "")); 
+0

謝謝你!它感覺我永遠都在吮吸! – LueTm

+0

啊!有時它也會在點之前添加標籤。所以我想我正在尋找的是一個正則表達式替換,它刪除了{和}之間的所有xml標籤和空格......我試圖找出一個。如果你更快,我會很感激:) – LueTm

+0

我不明白,你能更具體嗎? –