RegExp在双引号内查找/替换换行符,不影响双引号外的换行符

时间:2014-10-13 10:09:39

标签: php regex csv

我有一个CSV文件,由于包含新行字符的字段而导致导入问题。由于CSV导入器将每个换行视为一个新行,因此字段中的换行符会变得混乱。

因此,我想用<br>替换双引号内的新行,将“实际”换行符置于双引号之外。

第一步是能够创建正则表达式以获取文本文件中的换行符。

(\n|\r)

但在此之后我迷路了,因为我在这个表达式中找不到xxx:

(")(xxx)(\n|\r)(xxx)(") 

一种解决方案,让“真正的”新线条不受影响。

结论:如何替换字段中的每个换行符,并用双引号括起来<br>

我现在正在使用sublime文本来测试正则表达式,但稍后它将在php应用程序中使用。

5 个答案:

答案 0 :(得分:2)

搜索模式:

("[^"\n]*)\r?\n(?!(([^"]*"){2})*[^"]*$)

替换模式:

$1<br>

RegEx Demo

答案 1 :(得分:1)

可以使用preg_replace_callback()将引用的部分与anonymous function匹配:

$str = preg_replace_callback('~"[^"]+"~', function ($m) {
  return preg_replace('~\r?\n~', "<br>", $m[0]);
}, $str);

$m[0]对应于整个模式的匹配。

Test at eval.in; Regex FAQ

答案 2 :(得分:1)

CSV格式很复杂,在一般情况下,无法使用正则表达式可靠地解析。我的建议是使用解析器,例如,parsecsv-for-php处理引用的换行符非常不错:

$str = <<<EOF
42,okay,"okay too","here
be
""dragons""!",43

EOF;

$csv = new parseCSV();
$csv->heading = false;
$result = $csv->parse_string($str);

结果:

array(1) {
  [0]=>
  array(5) {
    [0]=>
    string(2) "42"
    [1]=>
    string(4) "okay"
    [2]=>
    string(8) "okay too"
    [3]=>
    string(18) "here
be
"dragons"!"
    [4]=>
    string(2) "43"
  }
}

答案 3 :(得分:0)

试试这个:

<?php

  $line = "\"abc\",\"\n\",\"def\"\n";
  $line = preg_replace('/"(.*?)\\n(.*?)"/', "\"$1<br>$2\"", $line);

?>

使用此输入:

"abc","\n","def"\n

打印此输出:

"abc","<br>","def"\n

答案 4 :(得分:0)

使用html5拖放导入csv文件时遇到了同样的问题。我使用下面的(javascript)修复程序,它对我有效。

//Fix: if there are any line breaks in between column values, then that column value will be wrapped in double quotes
//first get all the double quoted values list using regex
var lineBreakList = textcontent.match(/(["'])(\\?)[\s\S]*?\1/g);
//search for line breaks using regex, if found replace it with empty value
lineBreakList.forEach(function (item) {
    textcontent = textcontent.replace(item, item.replace(/\r?\n|\r/g, ''));
});

希望这会有所帮助:)