是否有一个简单的方法来转换字符串标题大小写?例如,约翰·史密斯变成了约翰·史密斯。我不是在寻找像John Resig的解决方案那样复杂的东西,只是(希望)一些一两行代码。


当前回答

我们已经在办公室进行了讨论,我们认为试图自动纠正人们输入姓名的方式,以您希望的方式进行,这可能充满了问题。

我们已经提出了几种不同类型的自动大写不成立的情况,这些仅仅是英语名称,每种语言都有自己的复杂性。

每个名字首字母大写的问题:

•像IBM这样的首字母缩写不允许输入,会变成IBM。

•McDonald这个名字会变成McDonald,这是不正确的,同样的东西也是MacDonald。

•像Marie-Tonks这样的双筒名字会变成Marie-Tonks。

O 'Connor这样的名字会变成O 'Connor。

对于其中的大多数,你可以编写自定义规则来处理它,然而,这仍然与以前的缩略语有问题,你会得到一个新的问题:

•添加一个规则来修复Mac的名称,如MacDonald,将打破名称,如Macy,将其变成Macy。

我们提出的唯一解决方案是永远不会不正确的是大写每一个字母,这是一个蛮力的方法,DBS似乎也使用。

因此,如果你想自动化这个过程,没有一个字典,每个名字和单词,以及它应该如何大写,这是不可能的。如果你没有一个规则,涵盖一切,不要使用它,因为它只会惹恼你的用户,并提示那些想要正确输入他们的名字的人去其他地方。

其他回答

使用/\S+/g支持变音符:

function toTitleCase(str) replace str.replace(/\S+/g, str => str.charAt(0). toupbelise (str.substr, 1); 的 控制台(toTitleCase(“一个城市叫orebro”);-一个叫Orebro的城市

然而:“阳光(黄色)”⇒“阳光(黄色)”

https://lodash.com/docs/4.17.11#capitalize

使用Lodash库!!更可靠的

_.capitalize('FRED'); => 'Fred'

只是另一个版本的混合。这也将检查字符串是否。长度为0:

String.prototype.toTitleCase = function() {
    var str = this;
    if(!str.length) {
        return "";
    }
    str = str.split(" ");
    for(var i = 0; i < str.length; i++) {
        str[i] = str[i].charAt(0).toUpperCase() + (str[i].substr(1).length ? str[i].substr(1) : '');
    }
    return (str.length ? str.join(" ") : str);
};

如果你需要一个语法正确的答案:

这个答案考虑了介词,如“of”,“from”,… 输出将生成您希望在论文中看到的编辑风格的标题。

toTitleCase函数

考虑此处列出的语法规则的函数。 该函数还合并空格和删除特殊字符(根据需要修改regex)

const toTitleCase = (str) => {
  const articles = ['a', 'an', 'the'];
  const conjunctions = ['for', 'and', 'nor', 'but', 'or', 'yet', 'so'];
  const prepositions = [
    'with', 'at', 'from', 'into','upon', 'of', 'to', 'in', 'for',
    'on', 'by', 'like', 'over', 'plus', 'but', 'up', 'down', 'off', 'near'
  ];

  // The list of spacial characters can be tweaked here
  const replaceCharsWithSpace = (str) => str.replace(/[^0-9a-z&/\\]/gi, ' ').replace(/(\s\s+)/gi, ' ');
  const capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.substr(1);
  const normalizeStr = (str) => str.toLowerCase().trim();
  const shouldCapitalize = (word, fullWordList, posWithinStr) => {
    if ((posWithinStr == 0) || (posWithinStr == fullWordList.length - 1)) {
      return true;
    }

    return !(articles.includes(word) || conjunctions.includes(word) || prepositions.includes(word));
  }

  str = replaceCharsWithSpace(str);
  str = normalizeStr(str);

  let words = str.split(' ');
  if (words.length <= 2) { // Strings less than 3 words long should always have first words capitalized
    words = words.map(w => capitalizeFirstLetter(w));
  }
  else {
    for (let i = 0; i < words.length; i++) {
      words[i] = (shouldCapitalize(words[i], words, i) ? capitalizeFirstLetter(words[i], words, i) : words[i]);
    }
  }

  return words.join(' ');
}

确保正确性的单元测试

import { expect } from 'chai';
import { toTitleCase } from '../../src/lib/stringHelper';

describe('toTitleCase', () => {
  it('Capitalizes first letter of each word irrespective of articles, conjunctions or prepositions if string is no greater than two words long', function(){
    expect(toTitleCase('the dog')).to.equal('The Dog'); // Capitalize articles when only two words long
    expect(toTitleCase('for all')).to.equal('For All'); // Capitalize conjunctions when only two words long
    expect(toTitleCase('with cats')).to.equal('With Cats'); // Capitalize prepositions when only two words long
  });

  it('Always capitalize first and last words in a string irrespective of articles, conjunctions or prepositions', function(){
    expect(toTitleCase('the beautiful dog')).to.equal('The Beautiful Dog');
    expect(toTitleCase('for all the deadly ninjas, be it so')).to.equal('For All the Deadly Ninjas Be It So');
    expect(toTitleCase('with cats and dogs we are near')).to.equal('With Cats and Dogs We Are Near');
  });

  it('Replace special characters with space', function(){
    expect(toTitleCase('[wolves & lions]: be careful')).to.equal('Wolves & Lions Be Careful');
    expect(toTitleCase('wolves & lions, be careful')).to.equal('Wolves & Lions Be Careful');
  });

  it('Trim whitespace at beginning and end', function(){
    expect(toTitleCase(' mario & Luigi superstar saga ')).to.equal('Mario & Luigi Superstar Saga');
  });

  it('articles, conjunctions and prepositions should not be capitalized in strings of 3+ words', function(){
    expect(toTitleCase('The wolf and the lion: a tale of two like animals')).to.equal('The Wolf and the Lion a Tale of Two like Animals');
    expect(toTitleCase('the  three Musketeers  And plus ')).to.equal('The Three Musketeers and Plus');
  });
});

请注意,我从提供的字符串中删除了相当多的特殊字符。您将需要调整正则表达式以满足项目的需求。

更简单的高性能版本,具有简单的缓存。

var TITLE_CASE_LOWER_MAP = { 'a': 1, 'an': 1, 'and': 1, 'as': 1, 'at': 1, 'but': 1, 'by': 1, 'en':1, 'with': 1, 'for': 1, 'if': 1, 'in': 1, 'of': 1, 'on': 1, 'the': 1, 'to': 1, 'via': 1 }; // LEAK/CACHE TODO: evaluate using LRU. var TITLE_CASE_CACHE = new Object(); toTitleCase: function (title) { if (!title) return null; var result = TITLE_CASE_CACHE[title]; if (result) { return result; } result = ""; var split = title.toLowerCase().split(" "); for (var i=0; i < split.length; i++) { if (i > 0) { result += " "; } var word = split[i]; if (i == 0 || TITLE_CASE_LOWER_MAP[word] != 1) { word = word.substr(0,1).toUpperCase() + word.substr(1); } result += word; } TITLE_CASE_CACHE[title] = result; return result; },