如何将字符串格式化为标题大小写?
这是一个在 C# 中执行此操作的简单静态方法:
public static string ToTitleCaseInvariant(string targetString)
{
return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(targetString);
}
在可能会招致挑剔者愤怒的情况下,我会谨慎地自动将所有空格前面的单词转大写。
我至少会考虑为冠词和连词等例外情况实现一个字典。看哪:
《美女与野兽》
当涉及到专有名词时,事情就变得更加难看。
这是一个 Perl 解决方案 http://daringfireball.net/2008/05/title_case
这是一个 Ruby 解决方案 http://frankschmitt.org/projects/title-case
这是一个 Ruby 单行解决方案:http://snippets.dzone.com/posts/show/4702
'some string here'.gsub(/\b\w/){$&.upcase}
单行代码所做的是使用正则表达式将每个单词的第一个字符替换为其大写版本。
要在 C 语言中使用它 - 使用 ascii 代码 (http://www.asciitable.com/) 查找 char 的整数值并从中减去 32。
如果您打算接受 a-z 和 A-Z 之外的字符,那么这是一个糟糕的解决方案。
例如:ASCII 134:å,ASCII 143:Å。
使用算术可以得到:ASCII 102: f
使用库调用,不要假设您可以对角色使用整数算术来返回有用的东西。 Unicode 是棘手。
在 Silverlight 中,
ToTitleCase
类中没有 TextInfo
。
这是一个简单的基于正则表达式的方法。
注意:Silverlight 没有预编译的正则表达式,但对我来说,这种性能损失不是问题。
public string TitleCase(string str)
{
return Regex.Replace(str, @"\w+", (m) =>
{
string tmp = m.Value;
return char.ToUpper(tmp[0]) + tmp.Substring(1, tmp.Length - 1).ToLower();
});
}
在 Perl 中:
$string =~ s/(\w+)/\u\L$1/g;
这甚至在常见问题解答中。
在Java中,可以使用以下代码。
public String titleCase(String str) {
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (i == 0) {
chars[i] = Character.toUpperCase(chars[i]);
} else if ((i + 1) < chars.length && chars[i] == ' ') {
chars[i + 1] = Character.toUpperCase(chars[i + 1]);
}
}
return new String(chars);
}
类似 Excel 的正确:
public static string ExcelProper(string s) {
bool upper_needed = true;
string result = "";
foreach (char c in s) {
bool is_letter = Char.IsLetter(c);
if (is_letter)
if (upper_needed)
result += Char.ToUpper(c);
else
result += Char.ToLower(c);
else
result += c;
upper_needed = !is_letter;
}
return result;
}
http://titlecase.com/
有一个 API
Excel中有一个内置公式
PROPER(n)
。
很高兴看到我不必自己写!
这是 Python 中的实现:https://launchpad.net/titlecase.py
以及我刚刚用 C++ 完成的此实现的端口:http://codepad.org/RrfcsZzO
这是一个如何执行此操作的简单示例:
public static string ToTitleCaseInvariant(string str)
{
return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str);
}
我认为使用 CultureInfo 并不总是可靠的,这是手动操作字符串的简单而方便的方法:
string sourceName = txtTextBox.Text.ToLower();
string destinationName = sourceName[0].ToUpper();
for (int i = 0; i < (sourceName.Length - 1); i++) {
if (sourceName[i + 1] == "") {
destinationName += sourceName[i + 1];
}
else {
destinationName += sourceName[i + 1];
}
}
txtTextBox.Text = desinationName;
在 C# 中
using System.Globalization;
using System.Threading;
protected void Page_Load(object sender, EventArgs e)
{
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
Response.Write(textInfo.ToTitleCase("WelcometoHome<br />"));
Response.Write(textInfo.ToTitleCase("Welcome to Home"));
Response.Write(textInfo.ToTitleCase("Welcome@to$home<br/>").Replace("@","").Replace("$", ""));
}
在 C# 中你可以简单地使用
CultureInfo.InvariantCulture.TextInfo.ToTitleCase(str.ToLowerInvariant())
无需使用现成函数,将字符串转换为标题大小写的超简单低级算法:
convert first character to uppercase.
for each character in string,
if the previous character is whitespace,
convert character to uppercase.
这假设“将字符转换为大写”将正确执行此操作,无论字符是否区分大小写(例如“+”)。
这里有一个 C++ 版本。它有一组不可大写的单词,例如代词和介词。但是,如果您要处理重要文本,我不建议自动化此过程。
#include <iostream>
#include <string>
#include <vector>
#include <cctype>
#include <set>
using namespace std;
typedef vector<pair<string, int> > subDivision;
set<string> nonUpperCaseAble;
subDivision split(string & cadena, string delim = " "){
subDivision retorno;
int pos, inic = 0;
while((pos = cadena.find_first_of(delim, inic)) != cadena.npos){
if(pos-inic > 0){
retorno.push_back(make_pair(cadena.substr(inic, pos-inic), inic));
}
inic = pos+1;
}
if(inic != cadena.length()){
retorno.push_back(make_pair(cadena.substr(inic, cadena.length() - inic), inic));
}
return retorno;
}
string firstUpper (string & pal){
pal[0] = toupper(pal[0]);
return pal;
}
int main()
{
nonUpperCaseAble.insert("the");
nonUpperCaseAble.insert("of");
nonUpperCaseAble.insert("in");
// ...
string linea, resultado;
cout << "Type the line you want to convert: " << endl;
getline(cin, linea);
subDivision trozos = split(linea);
for(int i = 0; i < trozos.size(); i++){
if(trozos[i].second == 0)
{
resultado += firstUpper(trozos[i].first);
}
else if (linea[trozos[i].second-1] == ' ')
{
if(nonUpperCaseAble.find(trozos[i].first) == nonUpperCaseAble.end())
{
resultado += " " + firstUpper(trozos[i].first);
}else{
resultado += " " + trozos[i].first;
}
}
else
{
resultado += trozos[i].first;
}
}
cout << resultado << endl;
getchar();
return 0;
}
使用 Perl 你可以做到这一点:
my $tc_string = join ' ', map { ucfirst($\_) } split /\s+/, $string;