按换行符分隔字符串,并保留带引号的句段

时间:2019-02-14 18:06:35

标签: javascript regex split

我有一个csv文件,该文件被读取为字符串,并且需要通过换行符分隔该字符串,并保留带引号的句段。使用引号的原因是因为文件的某些字段中包含换行符。

基本上,我有一个像这样的文件(我使用|表示分隔符):

  

这是|一个|线

     

这是|也行| “但是这个字段有

     

换行符”

     

这是|另一个线

我知道我可以在.split()函数中使用正则表达式,但是遇到了麻烦。有人可以帮忙吗?

我期望一个像 ["This is | a | line", "This is | a line too | but this field has\na line break", "This is | another | line"]

4 个答案:

答案 0 :(得分:3)

作为最简单的解决方案,我们可以首先标记(用一些标识符替换)line breaks 我们不想拆分成的位置。

然后在所有其他换行符处进行拆分,并最终将保留的换行符标识符替换为line breaks again(\ n).

arr = str.replace(/("[\s\S]*?")/g, (m, cg) => {
        return cg.replace(/\n/g, "LINE-BREAK-TO-PRESERVE");
      })
      .split('\n')
      .filter(i => Boolean(i.trim()))
      .map(i => i.replace(/LINE-BREAK-TO-PRESERVE/g, '\n'));

以上代码应能轻松满足您的目的:)

答案 1 :(得分:0)

老实说,这是一个非常简单的问题,即使正则表达式也显得过于矫kill过正。我只需要遍历字符串,每当您发现换行符并且不在引号内时,请将到目前为止找到的子字符串推入数组即可:

var arr = []
var inQuote = false;
var str = `This is | a | line
This is | a line too | "but this field has
a line break"
This is | another | line`
for (var pos = 0; pos < str.length; pos++) {
    if (str.charAt(pos) == "\n" && !inQuote) {
        arr.push(str.slice(0, pos));
        str = str.slice(pos + 1);
        pos = 0;
    } else if (str.charAt(pos) == '"') {
        inQuote = !inQuote;
        // if you want to get rid of the quotes:
        str = str.slice(0, pos) + str.slice(pos + 1)
        pos--
    }
}
arr.push(str)
console.log(arr)

答案 2 :(得分:-1)

尝试一下;

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

演示: https://regex101.com/r/wL9sQ4/82

答案 3 :(得分:-1)

在另一个答案中,使用循环可能会更好,因为即使知道分隔符,也很难检查引号是否在数据中间(作为文字)或引号是否充当报价。

也就是说,此正则表达式应满足特定情况的要求:

/(?<!\|\s+"[\w\s]+)\n/
console.log(
`This is | a | line
This is | a line too | "but this field has
a line break"
This is | another | line`.split(/(?<!\|\s+"[\w\s]+)\n/)
)

?<!是负向后看的,这意味着仅当括号中的部分不匹配时,才会匹配不在括号中的部分(\n)。

括号中的部分是分隔符(|),后跟一个以上的空格\s+,后跟引号",然后是单词和空格的混合。 / p>

希望这会有所帮助。可以根据需要将\s+更改为\s*,也可以将[\w\s]+更改为[^"]*

Demo