2013-12-09 36 views
0

我想寫一個正則表達式來匹配出現在兩個字符之間的所有字符串(很可能是" - 雙引號)。這是我在嘗試解析csv文件中的一行時經常遇到的場景。正則表達式提取所有在引號

所以我有這樣一個樣本行:

"Smith, John",25,"21/45, North Avenue",IBM 

試過以下的正則表達式:

"(.*)" 

但有些獲取如下:

http://regexr.com?37ie3

我期待輸出如下:

Smith, John 
25 
21/45, North Avenue 
IBM 

我寫的正則表達式試圖捕獲在我的示例中的"之間的內容。但是,以上是我期望的輸出。

雖然有一種含糊不清的情況:我不是在尋找像這樣的匹配:,25,。這有點讓我懷疑在這裏正則表達式是否可行。

寫這個的正確方法是什麼?

+1

' 「([^」] *) 「'或'」「'可以工作,但它會創建另一個(*?)問題 –

+0

你使用哪種語言的正則表達式? –

+0

@SalmanA你能解釋一下有問題的場景嗎? – deostroll

回答

1

如果你真的想ROLL你自己的CSV解析器,你需要教你的正則表達式幾條規則:

  1. 只要字段可以不加引號它不包含引號,逗號或換行符。
  2. 帶引號的字段可能包含任何字符;報價通過加倍逃脫。
  3. 逗號用作分隔符。

所以,一個CSV字段相匹配,您可以使用下面的正則表達式:

(?mx)  # Verbose, multiline mode 
(?<=^|,) # Assert there is a comma or start of line before the current position. 
(?:   # Start non-capturing group: 
"   # Either match an opening quote, followed by 
(?:  # a non-capturing group: 
    ""  # Either an escaped quote 
|   # or 
    [^"]+  # any characters except quotes 
)*   # End of inner non-capturing group, repeat as needed. 
"   # Match a closing quote. 
|   # OR 
[^,"\r\n]+ # Match any number of characters except commas, quotes or newlines 
)   # End of outer non-capturing group 
(?=,|$)  # Assert there is a comma or end-of-line after the current position 

看到它live on regex101.com

+0

我做對了嗎? - > http://regexr.com?37ier – deostroll

+0

你確定引號會以.net風格轉義嗎? –

+0

@CasimiretHippolyte我不會過分擔心目標語言以及某些必需的字符如何逃脫。也許即使引用的字符可能會有所不同......即。它可能不是''';它可能是'''而不是任何標點符號...底線它不是我會擔心的... – deostroll

0

首先,這隻會捕獲一個組。其次,你需要非貪婪:

(?:"(.*?)") 

這並不能解決你在單一行中多個匹配的問題。 這裏有兩個例子:

import re 
string = '"Smith, John",25,"21/45, North Avenue",IBM' 
pattern = r'(?:"(.*?)")' 
re.findall(pattern, string) 
> ['Smith, John', '21/45, North Avenue'] 

在C#:

string pattern = @"(?:\""(.*?)\"")"; 
string input = @"\""Smith, John\"",25,\""21/45, North Avenue\"",IBM'"; 
foreach (Match m in Regex.Matches(input, pattern)) 
    Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index); 
相關問題