使用 JavaScript 转换文本字符串

Transform string of text using JavaScript

我正在编写一个代码,将文本字符串运行sform 成一个句子大小写,它也将保留首字母缩略词。我确实在 Whosebug 中探索过类似的帖子,但是,我找不到适合我要求的帖子。

我已经完成运行首字母缩略词和句子中第一个字母的形成。但是,我 运行 遇到其他问题,例如句子中的某些字母仍然是大写,尤其是双引号 (" ") 和驼峰式文本中和之后的文本。

以下是我目前正在处理的代码,我需要有人帮我优化代码并解决问题。

String.prototype.toSentenceCase = function() {
  var i, j, str, lowers, uppers;
  str = this.replace(/(^\w{1}|\.\s*\w{1})/gi, function(txt) {
    return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
  });

  
  // Certain words such as initialisms or acronyms should be left uppercase
  uppers = ['Id', 'Tv', 'Nasa', 'Acronyms'];
  for (i = 0, j = uppers.length; i < j; i++)
    str = str.replace(new RegExp('\b' + uppers[i] + '\b', 'g'),
      uppers[i].toUpperCase());

 // To remove Special caharacters like ':' and '?'
    str = str.replace(/[""]/g,'');
    str = str.replace(/[?]/g,'');
    str = str.replace(/[:]/g,' - ');

return str;
}

输入:玩转:这是文本的“字符串”,需要将其转换为句子大小写,同时保持首字母缩略词,就像美国宇航局一样。

当前输出:试一试 - 这是一个文本字符串,需要将其转换为句子大小写,同时保持首字母缩略词,就像 NASA 一样。

预期输出:试一试 - 这是一串文本,需要将其转换为句子大小写,同时保持首字母缩略词,就像 NASA 一样。

这是初始代码的可运行版本(我稍微修改了输入字符串):

String.prototype.toSentenceCase = function() {
  var i, j, str, lowers, uppers;
  str = this.replace(/(^\w{1}|\.\s*\w{1})/gi, function(txt) {
    return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
  });

  
  // Certain words such as initialisms or acronyms should be left uppercase
  uppers = ['Id', 'Tv', 'Nasa', 'Acronyms'];
  for (i = 0, j = uppers.length; i < j; i++)
    str = str.replace(new RegExp('\b' + uppers[i] + '\b', 'g'),
      uppers[i].toUpperCase());

 // To remove Special caharacters like ':' and '?'
    str = str.replace(/[""]/g,'');
    str = str.replace(/[?]/g,'');
    str = str.replace(/[:]/g,' - ');

return str;
}

const input = `play around: This is a "String" Of text, which needs to be cONVERTED to Sentence Case at the same time keeping the Acronyms as it is like Nasa. another sentence. "third" sentence starting with a quote.`
const result = input.toSentenceCase()
console.log(result)


I ran into other issues like some letters in the sentence are still in Uppercase, especially texts in and after Double Quotes (" ") and camelcase texts.

一些字母保持大写,因为您没有在代码中的任何地方调用 .toLowerCase()。 Expect 在开头,但该正则表达式仅针对句子的首字母,而不是其他字母。

首先小写所有字母,然后大写一些字母(首字母缩写词和句子的首字母)会很有帮助。所以,让我们一开始就调用.toLowerCase()

String.prototype.toSentenceCase = function() {
  var i, j, str, lowers, uppers;

  str = this.toLowerCase();

  // ...

  return str;
}

接下来,让我们看一下这个正则表达式:

/(^\w{1}|\.\s*\w{1})/gi

括号是不必要的,因为替换函数中没有使用捕获组。 {1} 量词也是不必要的,因为默认情况下 \w 只匹配一个字符。所以我们可以像这样简化正则表达式:

/^\w|\.\s*\w/gi

此正则表达式从输入字符串中找到两个匹配项:

  • p
  • . a

两个匹配项都只包含一个字母 (\w),因此在替换函数中,我们可以安全地调用 txt.toUpperCase() 而不是当前更复杂的表达式 (txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase())。我们还可以使用箭头函数:

String.prototype.toSentenceCase = function() {
  var i, j, str, lowers, uppers;

  str = this.toLowerCase();

  str = str.replace(/^\w|\.\s*\w/gi, (txt) => txt.toUpperCase());

  // ...

  return str;
}

但是,第三个句子的首字母不是大写的,因为这个句子是以引号开头的。因为无论如何我们都要去掉引号和问号,所以让我们从头开始吧。

让我们也简化和组合正则表达式:

// Before
str = str.replace(/[""]/g,'');
str = str.replace(/[?]/g,'');
str = str.replace(/[:]/g,' - ');

// After
str = str.replace(/["?]/g,'');
str = str.replace(/:/g,' - ');

所以:

String.prototype.toSentenceCase = function() {
  var i, j, str, lowers, uppers;

  str = this;

  str = str.toLowerCase();

  str = str.replace(/["?]/g,'');
  str = str.replace(/:/g,' - ');

  str = str.replace(/^\w|\.\s*\w/gi, (txt) => txt.toUpperCase());

  // ...

  return str;
}

现在第三个句子的首字母大写正确了。那是因为当我们将首字母大写时,第三句不再以引号开头(因为我们已经删除了引号)。

剩下的就是大写首字母缩略词了。在您的正则表达式中,您可能还想使用 i 标志来进行不区分大小写的匹配。

不使用 for 循环,而是可以使用单个正则表达式来查找所有匹配项并将它们大写。这也使我们能够摆脱大部分变量。像这样:

String.prototype.toSentenceCase = function() {
  var str;

  str = this;

  str = str.toLowerCase();

  str = str.replace(/["?]/g,'');
  str = str.replace(/:/g,' - ');

  str = str.replace(/^\w|\.\s*\w/gi, (txt) => txt.toUpperCase());

  str = str.replace(/\b(id|tv|nasa|acronyms)\b/gi, (txt) => txt.toUpperCase());

  return str;
}

看起来我们现在得到了正确的结果!

不过还有三件事:

  1. 我们可以修改 this 并链接方法调用,而不是创建和改变 str 变量。
  2. txt 变量重命名为 match 变量可能有意义,因为它们是正则表达式匹配项。
  3. 修改内置对象的原型不是一个好主意。创建一个新函数是一个更好的主意。

这是最终代码:

function convertToSentenceCase(str) {
  return str
    .toLowerCase()
    .replace(/["?]/g, '')
    .replace(/:/g, ' - ')
    .replace(/^\w|\.\s*\w/gi, (match) => match.toUpperCase())
    .replace(/\b(id|tv|nasa|acronyms)\b/gi, (match) => match.toUpperCase())
}

const input = `play around: This is a "String" Of text, which needs to be cONVERTED to Sentence Case at the same time keeping the Acronyms as it is like Nasa. another sentence. "third" sentence starting with a quote.`
const result = convertToSentenceCase(input)
console.log(result)