有没有更好的方法来清洁琴弦?

Is there a better way to clean a string?

目前,这是我的代码。

function clean_string(raw_string) {
    A =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 1234567890".split(
            ""
        );
    var cleaned_string = raw_string.toLowerCase();
    for (i = 0; i < cleaned_string.length; i++) {
        if (!A.includes(cleaned_string[i])) {
            cleaned_string = setCharAt(cleaned_string, i, " ");
        }
    }
    cleaned_string = cleaned_string.replace(/\s\s+/g, " ");

    return cleaned_string;
}

function setCharAt(str, index, chr) {
    if (index > str.length - 1) return str;
    return str.substring(0, index) + chr + str.substring(index + 1);
}

我不知道正则表达式,使用正则表达式可能会更容易。这是我想要做的:

输入:Hello, David World 123!

输出:hello david world 123

.

输入:hELlo., <>;dAVId world .;- 123

输出:hello david world 123

.

输入: He.llo David, w!orld 123#

输出:he llo david w orld 123

.

基本上我想做的是用 space 替换 a-z0-9 以外的任何东西,然后删除双 spaces。换句话说,我只想要 a-z0-9 在我的结果中。我该怎么做?

P.S。该代码有效,但我认为它看起来很糟糕且效率很低。

编辑:抱歉,我的意思是我只想在输出中使用小写字母。我很笨

一个简单的解决方案是将所有字符转换为小写,将任何非 a-z、0-9 或 space 的字符替换为 space 字符,然后替换多个space 个字符,单个 space 个字符。

function sanitize(input) {
    return input
      .toLowerCase()
      .replace(/([^a-z\d\s]+)/g, ' ')
      .replace(/(\s+)/g, ' ');
}

console.log(sanitize('Hello, David World 123!'));
console.log(sanitize('hELlo.,     <>;dAVId  world  .;- 123'));
console.log(sanitize('He.llo     David,   w!orld 123#'));

这是一种使用正则表达式回调的方法:

var inputs = ["Hello, David World 123!", "hELlo.,     <>;dAVId  world  .;- 123", "He.llo     David,   w!orld 123#"];
for (var i=0; i < inputs.length; ++i) {
    var input = inputs[i];
    input = input.replace(/\w+/g, x => x.toLowerCase())
                 .replace(/[^\w_]+/g, " ");
    console.log(input);
}

这里的策略是做两个正则表达式替换。第一个查找输入中的所有单词并将它们转换为小写。第二个然后剥离所有非单词字符和白色 space,包括下划线,并替换为单个 space.

用一个简单的正则表达式来替换非字母数字字符,然后用另一个来连续删除多个 space 就可以了。

const clean = (input) => {
  const alphanumeric = input.replace(/[^a-zA-Z0-9]/g, ' ')
  const spaceless = alphanumeric.replace(/\s{2,}/g, ' ')
  
  console.log(spaceless.toLowerCase())
  return spaceless.toLowerCase()
}

clean("Hello, David World 123!")
clean("hELlo.,     <>;dAVId  world  .;- 123")
clean("He.llo     David,   w!orld 123#   ")

当然,函数可以简化为

const clean = (input) => {
  return input.replace(/[^a-zA-Z0-9]/g, ' ').
               replace(/\s{2,}/g, ' ').
               toLowerCase()
}

正则表达式解释:

[^a-zA-Z0-9]:匹配与 a-zA-Z0-9 不匹配的任何内容(任何非字母数字) \s{2,}:匹配连续出现两次或多次的space

您可以使用单个替换调用,或者仅小写大写字符,或者用单个 space.

替换 1 个或多个非单词字符

要区分替换和小写,您可以在正则表达式中使用捕获组并在回调函数中检查该组。

如果它匹配第 1 组,则有 1 个或多个大写字符 A-Z。

[
  "Hello, David World 123!",
  "hELlo.,     <>;dAVId  world  .;- 123",
  "He.llo     David,   w!orld 123#"
].forEach(s =>
  console.log(
    s.replace(/([A-Z]+)|[^\w_]+/g, (_, g1) => g1 ? g1.toLowerCase() : ' ')
  )
)