2010-12-18 56 views
7

你好正則表達式的專家,正則表達式 - 如何只使用一個引號內替換字符

從未有過一個字符串處理的問題,我無法用正則表達式解析到現在爲止,至少在一個優雅的方式步。這裏是樣本數據我的工作:

0,「SECTION1」,「(7)聯合國 美國以外的 ‘證書’交貨禁止由於兩個部分 339 1940章程,現行法律的68 /和 部分341 明確在他們的聲明中表示, 證書應提供的 公民,只有當這樣的人是在 在美國的時候,它 顯然,文件無法 ,並且不能在 美國之外遞送。「,http://www.google.co米/

1 「第2節」 ,, HTTP://www.google.com/

2 「SECTION3」, 「,,」,HTTP://www.google.com/

這是一個更大的CSV文件的一部分。用一個優雅的正則表達式,我只想用雙下劃線字符(_)替換雙引號內的所有逗號。正則表達式不會替換引號外的任何逗號,這很重要,因爲這會混淆CSV數據結構。

感謝, 湯姆

-

澄清:

對不起球員,我貼而不完全澄清我的情況的問題,所以讓我總結如下:

  • 假設引號內的引號已被轉義(由Excel保存的CSV文件中引號內的引號由""或表示等,所以它們很容易被預先替換)。
  • 我正在JavaScript中工作。

使用上面的示例文本,這裏是它應該是什麼樣子運行正則表達式,替換後(應該有一個共有5個替換的):

0,「SECTION1」,「(禁止7)的 美國 美國以外的「證書」交貨。由於兩個部分中的1940年的 339 statute_ 68 /和現行法律的 部分341 明確在他們的聲明中表示, 證書應提供的 citizen_只有在這樣的情況下維杜阿爾是 聯合States_內的一次 顯然,文件無法 並不能在 美國以外的交付「 HTTP://www.google.com/

1」。第2節」 ,, HTTP://www.google。COM/

2, 「SECTION3」, 「__」,HTTP://www.google.com/

+1

你如何在引號內轉義引號? – 2010-12-18 05:42:07

+0

@Assaf,好問題;請參閱我上面的說明。 – 10basetom 2010-12-18 17:56:37

回答

12

我會幫你的,但你必須承諾停止使用「優雅」這個詞。最近工作太辛苦了,值得休息。 :P

(?m),(?=[^"]*"(?:[^"\r\n]*"[^"]*")*[^"\r\n]*$) 

這匹配逗號,如果在逗號和記錄末尾之間有奇數個引號。我假設一個標準的CSV格式,其中一個記錄結束於未包含在引號中的下一行分隔符。行分隔符在引用字段內是合法的,如果引號是用另一個引號轉義的話就是引號。

根據您使用的是哪種正則表達式,您可能必須使用\r?$而不是$。例如,在.NET中,只有換行符(\n)被視爲行分隔符。但是在Java中,$\r\n中的\r之前匹配,但不匹配\r\n(除非您設置了UNIX_LINES模式)。

+0

艾倫摩爾,你是一個正規表達專家:-)。除了我在這裏(和其他地方)收到的所有解決方案之外,即使在我發佈我的說明之前,您的一個超級正則表達式也能夠完成我在我的問題中描述的內容。獎勵積分,和你的解決方案是「優雅」相比,我會想出解決方案(需要多個正則表達式和一個數組臨時存儲)。 – 10basetom 2010-12-18 18:04:05

+0

@Alan,除了我遺漏之外,我使用了你的正則表達式嗎?: - 除了記住比賽之外,還有其他用途嗎? – 10basetom 2010-12-18 18:34:48

+0

@ 10basetom:在很多正則表達式中,如果在分割正則表達式中使用捕獲組,則捕獲的任何內容都會隨常規記號添加到結果中。但我承認當時我甚至沒有想過這件事。我只是遵循經驗法則:如果一個非捕獲組可以完成這項工作,就不要使用捕獲組。每個額外的捕獲組都增加了一些額外的資源開銷,包括硬件和溼件(即作者要記住哪個組正在捕獲什麼)變得更加困難。 – 2010-12-18 21:08:34

3

正則表達式是不是匹配平衡的文本(即起點和終點報價)特別好。

一個天真的方法是重複應用這樣的事情(直到它不再匹配):

s/(^[^"]*(?:"[^"]*"[^"]*)*?)"([^",]*),([^"]*)"/$1"$2_$3"/ 

但不會與轉義引號工作。最好的(即最簡單,最可讀,最可靠的)解決方案是使用CSV文件解析器,逐個瀏覽所有字段值(隨時用逗號替換逗號),然後將其寫回到文件。

0

對不起,如果你不使用Python,其中是下面的代碼。 我沒有看到您使用哪種語言的任何指示。無論如何,我認爲代碼是完全可以理解的。

import re 

ch = '''0,"section1","(7) Delivery of 'certificate' outside the United States prohibited. 
Since both section 339 of the 1940 statute, 68/ and section 341 of the present law are explicit 
in their statement that the certificate shall be furnished the citizen, only if such individual 
is at the time within the United States, it is clear that the document could not and cannot be 
delivered outside the United States.",http://www.google.com/ 

1,"section2",,http://www.google.com/ 

2,"section3",",,",http://www.google.com/ 
''' 

poto = re.compile('("[^"]+")') 

def comma_replacement(match): 
    return match.group().replace(',','_') 

print poto.sub(comma_replacement , ch) 

該方法保持了2個相鄰逗號在線路

1 「第2節」 ,, HTTP://www.google.com/

不變。 這是你想要的嗎?

相關問題