替换字符串中的前N个出现次数

7

如何替换以下字符串中前 N 个空格和制表符的多个出现:

07/12/2017  11:01 AM             21523 filename with s p a c  e  s.js

I am expecting the following result:

07/12/2017|11:01|AM|21523|filename with s p a c  e  s.js

我知道不是很优雅的方法,只能通过在同一个字符串上调用replace N次来完成。

.replace(/\s+/, "|").replace(/\s+/, "|").replace(/\s+/, "|");

值得一提的是,我将在接近100万行的数据上运行此程序,因此性能至关重要。

1
@stealththeninja 楼主只想替换字符串中的前4个出现次数,因此保留文件名中的空格不变。 - Derek 朕會功夫
g将替换所有内容。但我只需要替换前n个出现的。 - Systems Rebooter
看起来你可以使用某种循环。 - Namaskar
7个回答

9
可能是这样的:

大概就像这样:

var txt = "07/12/2017  11:01 AM             21523 filename with s p a c  e  s.js";

var n = 0, N = 4;
newTxt = txt.replace(/\s+/g, match => n++ < N ? "|" : match);

newTxt; // "07/12/2017|11:01|AM|21523|filename with s p a c  e  s.js"

3

您可以使用计数器并将其递减。

var string = '07/12/2017  11:01 AM             21523 filename with s p a c  e  s.js',
    n = 4,
    result = string.replace(/\s+/g, s => n ? (n--, '|') : s);
    
console.log(result);

您可以用逻辑AND和OR替换三元表达式。

var string = '07/12/2017  11:01 AM             21523 filename with s p a c  e  s.js',
    n = 4,
    result = string.replace(/\s+/g, s => n && n-- && '|' || s);
    
console.log(result);


2

Derek和Nina提供了动态替换N个空格组的好方法。如果N是固定的,可以使用非空白标记(\S)来匹配并保留空格之间的组:

.replace(/\s+(\S+)\s+(\S+)\s+/, '|$1|$2|')


2

这里已经有一些非常好的答案了,但是既然你想要速度,我会选择使用单个 while 循环,像这样:

var logLine = '07/12/2017  11:01 AM             21523 filename with s p a c  e  s.js';
var N = 4;
while(--N + 1){
  logLine = logLine.replace(/\s+/, '|');
}
console.log(logLine);

这里有一个 JSFiddle 的链接:https://jsfiddle.net/2bxpygjr/

1

我会选择类似这样的东西。虽然我有点喜欢Derek的答案,所以我会查看他/她在其中做了什么。

var mytext = "some text separated by spaces and spaces and more spaces";
var iterationCount = 4;
while(iterationCount > 0)
  {
    mytext = mytext.replace(" ", "");
    iterationCount--;
  }
return mytext;

1
你自己的解决方案的递归版本怎么样?
function repalceLeadSpaces(str, substitution, n) {
    n = n || 0;
    if (!str || n <= 0) {
        return str;
    }
    str = str.replace(/\s+/, substitution);
    return n === 1 ? str : repalceLeadSpaces(str, substitution, n - 1)
}

0

你也可以:

  • split 在空格上,使用捕获组来保留间距;
  • 使用 map 将前 N 个空格元素替换为 |
  • join 将部分重新组合在一起。

const str = '07/12/2017  11:01 AM             21523 filename with s p a c  e  s.js'

const N = 4
const result = str.split(/(\s+)/).map((v, i) => i % 2 == 0 || i >= 2*N ? v : '|').join('')

console.log(result)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接