2011-03-22 38 views
2

我需要幫助來解析大量文本中的一些信息,基本上我正在導入一個PSD文件,並且想從中解析一些數據。在C#中的困難(對我來說)字符串解析(正則表達式?)

當中的文字是字符串,如這樣的:

\ r \ nj78876隨機文本STRINGS£75

現在我要做的就是搶適合這種格式的字符串(也許起始「\ r \ n」和結尾「£」可以是分隔符),並在開始時獲得代碼(j78876)和結束時的價格()。注意價格可能是更多的數字,即2。

我想然後抓住代碼,如j78876和每個字符串這樣的價格,因爲它們會發生多次(不同的代碼和價格)。

任何人都可以提出一種方法來做到這一點?

我對Regex不太熟練,所以指導會很棒。

謝謝。

注意:下面是實際文本的縮略圖(實際文件中有很多)。

提及此戰爭安西安娜提及此戰爭的3Com/H3CLibellé雷馬克大獎賽恩€\ r \ nJ9449A HP V1810-8G 交換機139.00 \ r \ nJ9450A HP V1810-24G開關359,00 \ r \ nEdge交換機 - 管理\ r \ nHP Layer 2交換機 - 託管式可堆疊交換機和機箱\ r \ nHP交換機2510系列\ r \nRéférenceAncienne référence3Com/H3CLibelléRemarque Prix en€\ r \ nJ9019B HP E2510-24交換機359,00 \ r \ nJ9020A HP E2510-48交換機599,00 \ r \ nJ9279A HP E2510-24G交換機779,00 \ r \ nJ9280A HP E2510-48G交換機1 569,00 \ r \ nHP交換機2520系列\ r \nRéférenceAncienneréférence 3Com/H3CLibelléRemarque Prix zh_CN \ r \ nJ9137A HP E2520-8-PoE交換機489,00 \ r \ nJ9138A HP E2520-24-PoE交換機779,00 \ r \ nJ9298A HP E2520-8G-PoE交換機749,00 \ r \ nJ9299A HP E2520- 24G-PoE交換機1 569,00 \ r \ nHP第2層和第3層交換機 - Managed Stackables and Chassis \ r \ n RBP僅爲推薦價格。 \ r \ NHP交換機2600系列\ r \ n參考安西安娜

更新 我發現這一點:

[\\r\\n](\w\d+\w).*?(\d+,\d\d)[\\r\\n] 

爲我工作在正則表達式瀏覽器的測試,但不會在我的C#代碼工作

Regex reg = new Regex(@"[\\r\\n](\w\d+\w).*?(\d+,\d\d)[\\r\\n]", RegexOptions.IgnoreCase); 
Match matched = reg.Match(str); 
if (matched.Success) 
{ 
    string code = matched.Groups[1].Value; 
    string currencyAmt = matched.Groups[2].Value; 
} 

最終更新: 在瀏覽器測試人員中,我不得不雙倍轉義\ r \ n - 在我的代碼中,這是沒有必要的。然後循環我使用循環答案的組。

foreach (Match match in Regex.Matches(content, @"[\r\n](?<code>\w\d+\w).*?(?<price>\d+,\d\d)[\r\n]", RegexOptions.IgnoreCase)) 
{ 
    string code = match.Groups["code"].Value; 
    string currencyAmt = match.Groups["price"].Value; 
} 
+0

你的意思是75的價格? – Marlon 2011-03-22 17:03:59

+3

這真的取決於「隨機文本字符串」可以包含哪些字符 - 包括空白信息。 – Jon 2011-03-22 17:06:47

+0

嗨喬恩,是的隨機文本是各種文本 - 段與空格,回車「\ r \ n」的等,但不包含英鎊符號 - 所以我想尋找一個「英鎊」和回到「\ r \ n」充當字符串令牌分隔符的種類。 – Simon 2011-03-22 17:37:49

回答

1

我會使用命名組來更容易地識別組。表達式的?<code>部分標識組。

你會想要使用匹配,正如你所說在你的文本中會出現幾個模式。通過他們所有這一切環路..

foreach (Match match in Regex.Matches(text, @"\r\n(?<code>\S+).*?(?<price>\d+)£")) 
{ 
    string code = match.Groups["code"].Value; 
    string currencyAmt = match.Groups["price"].Value; 
    Console.WriteLine(code); 
    Console.WriteLine(currencyAmt); 
} 
+0

試了一下,但沒有找到匹配。我在上面的問題中添加了實際文本的片段。 – Simon 2011-03-22 18:11:26

+0

如果你在模式中的英鎊之前加上空格,它會起作用嗎?我不是在我的計算機上在一分鐘內試用它... – 2011-03-22 19:17:57

+0

感謝您的輸入,它讓我朝正確的方向循環瀏覽匹配。 – Simon 2011-03-22 20:32:40

2

好的,你的問題是一個移動的目標。實際的文本樣本(與您的問題相矛盾)沒有英鎊。這裏有一個適應的表達:

new Regex(@"\r\n(\w+?).*?\s+(\d+?,\d\d)") 

在散文(這是一個性學習的網站畢竟):比賽爲「\ r \ n」繼之以任何字母數字直到你打空格,然後什麼,直到你打空格之後在逗號後面有兩位數字的號碼。捕獲斜體中的部分。

正如我所說,我不做Obj-C,因此無法測試它。有關如何使用它,請參閱these C# docs(以及其他答案)。

+0

誰說代碼必須以」j「開頭? – 2011-03-22 17:14:55

+0

對,我已經修復它任何字母數字代碼 – svoop 2011-03-22 17:20:07

+0

+1對我來說它應該工作 – 2011-03-22 18:22:42

3
Regex reg = new Regex(@"\r\n([a-z]\d+\w)\s.*\s(\d+\,?\d+?)\r\n", RegexOptions.IgnoreCase); 
string productCode, productCost; 
foreach (Match match in reg.Matches(str)) 
{ 
    productCode = match.Groups[1].Value; 
    productCost = match.Groups[2].Value; 
    //do something with values here 
} 

編輯是因爲我原來的答案是錯的。
根據您的示例上述作品。第一個參數,以新的正則表達式的
快速的正則表達式的解釋(:

@:讓我的字符串常量,使我不必到處添加額外的逃逸
\ r \ n:開頭
(即[az。 ] \ \:\ d + \ w)\ s:匹配您的產品代碼,我使用\ s來構造它,因爲它看起來是一致的空格
。*:匹配您的隨機生產描述字符串。 d + \,?\ d +?):匹配一個空格,然後是第二次捕獲某種貨幣
\ r \ n:以。

如果你提供了一個更大的樣本數據集,我可以微調正則表達式。

+0

剛格式化的代碼;) – 2011-03-22 17:14:21

+0

誰說代碼必須以「j」開頭? – 2011-03-22 17:15:48

+0

'[\ r \ n]'可能不是Simon所需要的,因爲它不會匹配「\ r \ n」。 – svoop 2011-03-22 17:50:46

0

最終的結果是這樣的:

foreach (Match match in Regex.Matches(content, @"[\r\n](?<code>\w\d+\w).*?(?<price>\d+,\d\d)[\r\n]", RegexOptions.IgnoreCase)) 
{ 
    string code = match.Groups["code"].Value; 
    string currencyAmt = match.Groups["price"].Value; 
} 
0

您添加樣本數據產生的問題比解決的問題多。我們是否應該將那些\r\n序列視爲回車+換行符(CRLF)或文字文本?此外,看起來空格字符已被插入隨機位置 - 在某些情況下,甚至在\r\n之間。哦,並且沒有磅符號(£),只有歐元符號(),並且它們絕不會像您最初指出的那樣與價格位於同一行。

如果該樣本確實代表了您的數據,那麼在開始搜索之前,您應該嘗試清理它(或讓提供給您的人員將其清理乾淨)。我做到了,所以我可以測試我的正則表達式;如果我做出了任何錯誤的假設,請讓我知道。這裏,它是:

Regex rgx = new Regex(@"^(\w+).*?(\d+,\d\d)(?:[\r\n]+|\z)", RegexOptions.Multiline); 

    string s = @"Référence Ancienne référence 3Com/H3C Libellé Remarque Prix en € 
J9449A HP V1810-8G Switch 139,00 
J9450A HP V1810-24G Switch 359,00 
Edge Switches - Managed 
HP Layer 2 Switches - Managed Stackables and Chassis 
HP Switch 2510 Series 
Référence Ancienne référence 3Com/H3C Libellé Remarque Prix en € 
J9019B HP E2510-24 Switch 359,00 
J9020A HP E2510-48 Switch 599,00 
J9279A HP E2510-24G Switch 779,00 
J9280A HP E2510-48G Switch 1 569,00 
HP Switch 2520 Series 
Référence Ancienne référence 3Com/H3C Libellé Remarque Prix en € 
J9137A HP E2520-8-PoE Switch 489,00 
J9138A HP E2520-24-PoE Switch 779,00 
J9298A HP E2520-8G-PoE Switch 749,00 
J9299A HP E2520-24G-PoE Switch 1 569,00 
HP Layer 2 and 3 Switches - Managed Stackables and Chassis 
The RBP is a recommended price only. 
HP Switch 2600 Series 
Référence Ancienne"; 

    foreach (Match m in rgx.Matches(s)) 
    { 
    Console.WriteLine("code: {0}; price: {1}", 
     m.Groups[1].Value, m.Groups[2].Value); 
    } 

輸出:

code: J9449A; price: 139,00 
code: J9450A; price: 359,00 
code: J9019B; price: 359,00 
code: J9020A; price: 599,00 
code: J9279A; price: 779,00 
code: J9280A; price: 569,00 
code: J9137A; price: 489,00 
code: J9138A; price: 779,00 
code: J9298A; price: 749,00 
code: J9299A; price: 569,00 

在多模式的^足以在一行的開頭來錨定匹配;您不必與行分隔符(\r\n)本身相匹配。您可以使用以相同的方式在末尾使用$,但這不起作用,因爲.NET不會將\r視爲行分隔符。相反,我做了這樣的徒手畫:(?:[\r\n]+|\z)

相關問題