当行也由\ r \ n分隔时,如何在两个选项卡之间的带引号的字符串之间删除\ r \ n?

时间:2014-10-02 18:17:11

标签: ruby regex csv

在Ruby 2.1.3中,我有一个表示标题的字符串,例如以制表符分隔的csv文件格式:

string = "helloworld\r\n14522\tAB-12-00420\t\"PROTOCOL \r\nRisk Effectiveness \r\nand Device Effectiveness In \r\Ebola Candidates \"\tData Collection only\t\t20\t"

我想在以协议开头的制表符分隔部分中删除“\ r \ n”,这样我就可以读完一个完整的标题为“在埃博拉候选人中的协议风险有效性和设备效率”....我想要最终结果是:

"helloworld\r\n14522\tAB-12-00420\t\"PROTOCOL Risk Effectiveness and Device Effectiveness In Heart Failure Candidates \"\tData Collection only\t\t20\t"

如果我不这样做,尝试通过CSV读取它会截断标题,所以我最终只读“PROTOCOL”而不是标题的其余部分。

请记住,我想在标题中删除一些不确定数量的\ r \ n字符(我将通过不同的标题进行解析)。我该如何做到这一点?我在想一个正则表达式可能就是这样......

2 个答案:

答案 0 :(得分:1)

不幸的是我不知道ruby,我要提供的解决方案不是很好,但是这里有:

由于ruby的regex实现不支持动态宽度lookbehinds,我无法想出一个匹配 你要删除的\r\n的模式。但是你可以替换这个正则表达式模式的所有匹配

(\t"?PROTOCOL[^\t]*)[\r\n]+

\1(已与第1组匹配的文字),直到模式不再匹配。只有一个替换不会删除\r\n的所有出现。 See demo.

我希望你能找到更好的解决方案。

答案 1 :(得分:1)

由于换行符(在引号之外)被视为分隔符,因此 您可以使用此正则表达式来隔离引用的字段,然后替换任何\r?\n只 在那个领域内。

然后,您可以将字符串传递给CSV模块。

共有3组组成整场比赛 1.分隔符
2.双引号字段
3非引用字段

需要使用replace-with-callback函数实现 在回调中,如果组2不为空,则单独替换所有CRLF Catenate goup 1 +替换(group2)+ group 3,然后返回catenation。

 # ((?:^|\t|\r?\n)[^\S\r\n]*)(?:("[^"\\]*(?:\\[\S\s][^"\\]*)*"(?:[^\S\r\n]*(?=$|\t|\r?\n)))|([^\t\r\n]*(?:[^\S\r\n]*(?=$|\t|\r?\n))))

 (                             # (1 start), Delimiter tab or newline
      (?: ^ | \t | \r? \n )
      [^\S\r\n]*                    # leading optional whitespaces
 )                             # (1 end)
 (?:
      (                             # (2 start), Quoted string field
           "
           [^"\\]* 
           (?: \\ [\S\s] [^"\\]* )*
           "
           (?:
                [^\S\r\n]*                    # trailing optional whitespaces
                (?= $ | \t | \r? \n )         # Delimiter ahead, tab or newline
           )
      )                             # (2 end)
   |                              # OR
      (                             # (3 start), Non quoted field
           [^\t\r\n]* 
           (?:
                [^\S\r\n]*                    # trailing optional whitespaces 
                (?= $ | \t | \r? \n )         # Delimiter ahead, tab or newline
           )
      )                             # (3 end)
 )