2013-03-27 69 views
0

我有一些XML,看起來像:XML的正則表達式與可選元素解析

<records> 
    <Customer> 
    <Reference>123</Reference> 
    <Name>John Smith</Name>  
    <Address1>1, The street</Address1> 
    <Address2>Upper Town Street</Address2> 
    <Address3>Anytown</Address3> 
    <Address4>County</Address4> 
    <PostCode>POS TCD</PostCode> 
    </Customer> 
</records> 

但其地址2是可選的,所以這也是有效的:

<records> 
    <Customer> 
    <Reference>123</Reference> 
    <Name>John Smith</Name>  
    <Address1>1, The street</Address1> 
    <Address3>Anytown</Address3> 
    <Address4>County</Address4> 
    <PostCode>POS TCD</PostCode> 
    </Customer> 
</records> 

(注:這是一個減少XML代碼段)

我有一個正確匹配指定地址2當下面的正則表達式:

<Reference>(?<Reference>.*)</Reference>[\w|\W]*<Name>(?<Name>.*)</Name>[\w|\W]*<Address1>(?<Address1>.*)</Address1>[\w|\W]*<Address2>(?<Address2>.*)</Address2> 

對於未指定Address2的情況它不起作用。 我得到的最接近如下:

<Reference>(?<Reference>.*)</Reference>[\w|\W]*<Name>(?<Name>.*)</Name>[\w|\W]*<Address1>(?<Address1>.*)</Address1>[\w|\W]*(<Address2>(?<Address2>.*)</Address2>)? 

相匹配,並填充參考,名稱和地址1兩個XML片段,但留下地址2在這兩種情況下的空白,而不是對上城街道的值地址2爲第一個片段。

另外:我知道使用XML解析器可能會更容易,但XML不乾淨,這應該是一個快速和簡單的解決方案(!)。我也知道,我可以將其分解成一組要解決的正則表達式,但現在這已成爲一個智力挑戰。我很想有一個解決方案。

回答

1

快速和骯髒的答案:

<Reference>(?<Reference>.*)</Reference>[\w\W]*?<Name>(?<Name>.*)</Name>[\w\W]*?<Address1>(?<Address1>.*)</Address1>[\w\W]*?(<Address2>(?<Address2>.*)</Address2>)? 

首先,我刪除了|;它不會傷害任何東西,但它是沒有必要的。 [\w\W]已經意味着一個字符,或者一個字符是而不是一個字符。像大多數其他元字符一樣,|在字符類中失去其特殊含義,並且只匹配它自己。

但重點是將*更改爲*?,使其非貪婪。每個[\w\W]*開始吞噬整個文本的其餘部分,然後回溯,以便它可以匹配下一個所需的部分(例如,<Name>(?<Name>.*)</Name>)。但Address2部分是而不是必需的,所以正則表達式引擎不會打擾回溯來接受它。

使量詞不貪婪反轉優先級:在它吞噬下一個字符之前,它首先嚐試匹配正則表達式的下一個部分。這確保Address2行可以匹配(如果存在),即使它是可選的。

但是,如果您的XML是按照您展示的方式進行格式化的,則元素之間的所有元素都是空白。我只會使用\s*,而不必擔心它匹配太多或太少。

+0

謝謝Alan。 | |好點性格,謝謝你的選擇。感謝您解釋清楚的答案。 – Jane 2013-03-28 09:10:28

2

而不是使用的,修正損壞並使用上最有趣的問題你的想法=)

並不解析文件的工具。在2013年解析是一個已解決的問題,不要試圖重新發明車輪。

就像你已經說過的,使用XML解析器。如果你想讓我給你一些這樣的東西,請在你原來的POST中添加你的語言。

我知道解析的最好的 &


RegEx match open tags except XHTML self-contained tags

+0

正如我在文章中所說的,我知道使用XML解析器會更容易,並且是解決它的正確方法,但是現在我想通過正則表達式解決這個問題。 – Jane 2013-03-27 14:43:33

+2

用你的想法解決更好的問題並修復你的XML =) – 2013-03-27 14:44:24