是否有一个简单的方法来转换字符串标题大小写?例如,约翰·史密斯变成了约翰·史密斯。我不是在寻找像John Resig的解决方案那样复杂的东西,只是(希望)一些一两行代码。
当前回答
如果你需要一个语法正确的答案:
这个答案考虑了介词,如“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');
});
});
请注意,我从提供的字符串中删除了相当多的特殊字符。您将需要调整正则表达式以满足项目的需求。
其他回答
我的清单是基于三个快速搜索。一个用于不大写的单词列表,一个用于完整的介词列表。
最后一个搜索建议,5个或5个字母以上的介词应该大写,这是我喜欢的。我的目的是非正式使用。我把“without”留在了他们的单词里,因为它是with的明显对应词。
所以它把首字母缩写,标题的第一个字母,以及大多数单词的第一个字母都大写。
它不打算处理带有大写锁的单词。我不想管这些。
function camelCase(str) { return str.replace(/((?:^|\.)\w|\b(?!(?:a|amid|an|and|anti|as|at|but|but|by|by|down|for|for|for|from|from|in|into|like|near|nor|of|of|off|on|on|onto|or|over|past|per|plus|save|so|than|the|to|to|up|upon|via|with|without|yet)\b)\w)/g, function(character) { return character.toUpperCase(); })} console.log(camelCase('The quick brown fox jumped over the lazy dog, named butter, who was taking a nap outside the u.s. Post Office. The fox jumped so high that NASA saw him on their radar.'));
下面是我的函数,它转换为标题大小写,但也保留了定义的首字母缩写为大写,小词为小写:
String.prototype.toTitleCase = function() {
var i, j, str, lowers, uppers;
str = this.replace(/([^\W_]+[^\s-]*) */g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
// Certain minor words should be left lowercase unless
// they are the first or last words in the string
lowers = ['A', 'An', 'The', 'And', 'But', 'Or', 'For', 'Nor', 'As', 'At',
'By', 'For', 'From', 'In', 'Into', 'Near', 'Of', 'On', 'Onto', 'To', 'With'];
for (i = 0, j = lowers.length; i < j; i++)
str = str.replace(new RegExp('\\s' + lowers[i] + '\\s', 'g'),
function(txt) {
return txt.toLowerCase();
});
// Certain words such as initialisms or acronyms should be left uppercase
uppers = ['Id', 'Tv'];
for (i = 0, j = uppers.length; i < j; i++)
str = str.replace(new RegExp('\\b' + uppers[i] + '\\b', 'g'),
uppers[i].toUpperCase());
return str;
}
例如:
"TO LOGIN TO THIS SITE and watch tv, please enter a valid id:".toTitleCase();
// Returns: "To Login to This Site and Watch TV, Please Enter a Valid ID:"
有一些很好的答案,但是,许多人使用正则表达式来查找单词,但是,由于某种原因,没有人使用正则表达式来替换第一个字符。为了解释,我将提供一个较长的解决方案和一个较短的解决方案。
长期解决方案(更具解释性)。通过使用正则表达式[^\s_\-/]*,我们可以找到句子中的每一个单词。随后,我们可以使用正则表达式。与单词中的第一个字符匹配。使用正则表达式版本的replace来替换这两个函数,我们可以像这样更改解决方案:
function toUpperCase(str){返回str.toUpperCase();} 函数capitalizeWord(word){返回word.replace(/。/,包含);} 函数大写(句子){返回句子。tolowercase()。替换(/ [/ ^ \ s_ \] * / g, capitalizeWord);} console.log(大写(“hello world”));//输出:Hello World
对于做同样事情的单个函数,我们将replace调用嵌套如下:
函数大写(句子){ 返回sentence.toLowerCase()。替换(/[^\s_\-/]*/g, function (word) { 返回word.replace(/。/,函数(ch){返回ch. touppercase ();}); }); } console.log(大写(“hello world”));//输出:Hello World
我对这个问题的简单版本是:
function titlecase(str){
var arr=[];
var str1=str.split(' ');
for (var i = 0; i < str1.length; i++) {
var upper= str1[i].charAt(0).toUpperCase()+ str1[i].substr(1);
arr.push(upper);
};
return arr.join(' ');
}
titlecase('my name is suryatapa roy');
与John Resig的解决方案一样功能齐全,但作为一行程序:(基于此github项目)
function toTitleCase(e){var t=/^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|vs?\.?|via)$/i;return e.replace(/([^\W_]+[^\s-]*) */g,function(e,n,r,i){return r>0&&r+n.length!==i.length&&n.search(t)>-1&&i.charAt(r-2)!==":"&&i.charAt(r-1).search(/[^\s-]/)<0?e.toLowerCase():n.substr(1).search(/[A-Z]|\../)>-1?e:e.charAt(0).toUpperCase()+e.substr(1)})};
console.log( toTitleCase( "ignores mixed case words like iTunes, and allows AT&A and website.com/address etc..." ) );
推荐文章
- 我如何检查如果一个变量是JavaScript字符串?
- 如何检测如果多个键被按下一次使用JavaScript?
- 如何通过history. pushstate获得历史变化的通知?
- 使用jQuery改变输入字段的类型
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?
- JavaScript DOM删除元素
- 将dd-mm-yyyy字符串转换为日期