检测换行符类型

vit*_*y-t 6 javascript node.js

在 JavaScript 中确定文本中使用的换行符类型的最有效(足够快速和可靠)方法是什么 - Unix 与 Windows。

在我的 Node 应用程序中,我必须读取大型 utf-8 文本文件,然后根据它们是使用 Unix 还是 Windows 换行符来处理它们。

当断线的类型不确定时,我想根据最有可能的断线来得出结论。

更新

根据我在下面的回答,我最终使用代码是.

Sam*_*ham 7

您首先需要寻找 LF。likesource.indexOf('\n')然后看看后面的字符是否是 CR like source[source.indexOf('\n')-1] === '\r'。这样,您只需找到换行符的第一个示例并与之匹配即可。总之,

function whichLineEnding(source) {
     var temp = source.indexOf('\n');
     if (source[temp - 1] === '\r')
         return 'CRLF'
     return 'LF'
}
Run Code Online (Sandbox Code Playgroud)

在 npm 模块中有两个流行的库示例: node-newlinecrlf-helper 第一个对整个字符串进行分割,这在您的情况下效率非常低。第二个使用正则表达式,在您的情况下它不够快。

但是,根据您的编辑,如果您想确定哪个更丰富。然后我将使用node-newline中的代码,因为它确实处理了这种情况。


Mir*_*ili 5

感谢@Sam-Graham。我试图产生一种优化的方式。此外,该函数的输出可以直接使用(参见下面的示例):

function getLineBreakChar(string) {
    const indexOfLF = string.indexOf('\n', 1)  // No need to check first-character
    
    if (indexOfLF === -1) {
        if (string.indexOf('\r') !== -1) return '\r'
        
        return '\n'
    }
    
    if (string[indexOfLF - 1] === '\r') return '\r\n'
    
    return '\n'
}
Run Code Online (Sandbox Code Playgroud)

注1:假设string是健康的(仅包含一种类型的换行符)。

注意2:假设您想要LF默认编码(当未找到换行符时)。


使用示例:

fs.writeFileSync(filePath,
        string.substring(0, a) +
        getLineBreakChar(string) +
        string.substring(b)
);
Run Code Online (Sandbox Code Playgroud)

这个实用程序也可能很有用:

const getLineBreakName = (lineBreakChar) =>
    lineBreakChar === '\n' ? 'LF' : lineBreakChar === '\r' ? 'CR' : 'CRLF'
Run Code Online (Sandbox Code Playgroud)


vit*_*y-t 2

最后,我根据简单的统计数据使用了自己的解决方案:

const {EOL} = require('os');

function getEOL(text) {
    const m = text.match(/\r\n|\n/g);
    const u = m && m.filter(a => a === '\n').length;
    const w = m && m.length - u;
    if (u === w) {
        return EOL; // use the OS default
    }
    return u > w ? '\n' : '\r\n';
}
Run Code Online (Sandbox Code Playgroud)

当没有换行符,或者它们的数量突然相等时,它将返回操作系统的默认 EOL。

更新

后来我通过进一步的实践发现,如果你想以同样的方式处理文本,无论它是Unix还是Windows编码,那么最有效的方法就是简单地将任何可能的Windows编码替换为Unix编码,然后根本不用担心任何验证:

text = text.replace(/\r\n/g, '\n'); // replace every \r\n with \n
Run Code Online (Sandbox Code Playgroud)