正则表达式 - 如何替换引号内的字符

时间:2010-12-18 05:31:54

标签: regex

Hello正则表达专家,

直到现在,我从未遇到过用正则表达式解决的字符串操作问题,至少以一种优雅的方式只使用一步。以下是我正在使用的示例数据:

  

0,“section1”,“(7)交付   美国境外的“证书”   禁止的国家。既然两节   1940年法规中的339,68 /和   本法第341条是   在他们的陈述中明确表示   证书应当提供   公民,只有这样的个人在   它在美国境内的时间   很清楚,该文件不能   并且不能在外面交付   美国。“,http://www.google.com/

     

1 “第2节” ,, HTTP://www.google.com/

     

2, “SECTION3”, “,,”,HTTP://www.google.com/

这是一个更大的CSV文件的一部分。使用一个优雅的正则表达式,我只想用双引号字符(_)替换双引号中出现的所有逗号。重要的是,正则表达式不会替换引号之外的任何逗号,因为这会弄乱CSV数据结构。

谢谢, 汤姆

-

澄清:

对不起,伙计们,我在没有完全澄清我的情况的情况下发布了这个问题,所以让我总结一下:

  • 假设引号内的引号已经转义(Excel保存的CSV文件中引号内的引号由"""""等表示,因此可以事先轻松替换它们。
  • 我在JavaScript中工作。

使用上面的示例文本,运行正则表达式替换后应该是它应该是什么样子(应该总共有5个替换):

  

0,“section1”,“(7)交付   美国境外的“证书”   禁止的国家。既然两节   1940年的法规中的339个/ 68   本法第341条是   在他们的陈述中明确表示   证书应当提供   公民_只有这样的个人在   在美国境内的时间吧   很清楚,该文件不能   并且不能在外面交付   美国。“,http://www.google.com/

     

1 “第2节” ,, HTTP://www.google.com/

     

2, “SECTION3”, “__”,HTTP://www.google.com/

3 个答案:

答案 0 :(得分:13)

我会帮助你,但你必须承诺停止使用“优雅”这个词。最近一直在努力工作,值得休息。 :P

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

如果在逗号和记录结尾之间有一个奇数引号,则匹配逗号。我假设一种标准的CSV格式,其中记录在未包含在引号中的下一行分隔符处结束。行分隔符在引用字段内是合法的,如果它们与另一个引号一起转义,则为引号。

根据您使用的正则表达式风格,您可能必须使用\r?$而不是$。例如,在.NET中,只有换行符(\n)被视为行分隔符。但在Java中,$\r\r\n之前匹配,但\r\n之间不匹配(除非您设置UNIX_LINES模式)。

答案 1 :(得分:3)

正则表达式在匹配平衡文本(即开始和结束引号)方面并不是特别擅长。

一种天真的方法是重复应用这样的东西(直到它不再匹配):

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

但这不适用于转义引号。最好的(即最简单,最易读,最可维护的)解决方案是使用CSV文件解析器,逐个查看所有字段值(随后用下划线替换逗号),然后写它退回到文件。

答案 2 :(得分: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,“section2”,, http://www.google.com/

不变。 这是你想要的正确的事吗?