给定任何字符串,我想创建一个代表字符串的智能首字母缩略词。如果你们中的任何人使用过JIRA,他们就能很好地完成这项工作。
例如,给出单词: Phoenix 它会生成 PHX 或者给出隐私事件管理这个词会创建 PEM
我有一些代码可以完成后者:
string.Join(string.Empty, model.Name
.Where(char.IsLetter)
.Where(char.IsUpper))
如果只有一个单词及其小写,则此案例不会处理。
但它没有考虑第一种情况。有任何想法吗?我正在使用C#4.5
答案 0 :(得分:4)
对于Phoenix => PHX,我想你需要根据已知缩写字典检查字符串。至于多字/骆驼案例支持,正则表达式是你的朋友!
var text = "A Big copy DayEnergyFree good"; // abbreviation should be "ABCDEFG"
var pattern = @"((?<=^|\s)(\w{1})|([A-Z]))";
string.Join(string.Empty, Regex.Matches(text, pattern).OfType<Match>().Select(x => x.Value.ToUpper()))
让我解释一下这里发生了什么,从正则表达式模式开始,它涵盖了匹配子串的几个案例。
// must be directly after the beginning of the string or line "^" or a whitespace character "\s"
(?<=^|\s)
// match just one letter that is part of a word
(\w{1})
// if the previous requirements are not met
|
// match any upper-case letter
([A-Z])
Regex.Matches方法返回一个MatchCollection,它基本上是一个ICollection,因此要使用LINQ表达式,我们调用OfType()将MatchCollection转换为IEnumerable。
Regex.Matches(text, pattern).OfType<Match>()
然后我们只选择匹配的值(我们不需要其他正则表达式匹配元数据)并将其转换为大写。
Select(x => x.Value.ToUpper())
答案 1 :(得分:1)
我能够提取出JIRA密钥生成器并将其发布到here。非常有趣,即使它的JavaScript很容易转换为c#。
答案 2 :(得分:1)
这是一个生成缩写词的简单函数。基本上,当该字符前面有空格时,会将字母或数字放在首字母缩写词中。如果字符串中没有空格,则将字符串返回。它不使用首字母缩写词大写,但是很容易修改。
您可以将其复制到代码中并开始使用。
结果如下。只是一个例子:
德勤私人有限公司-DPPL 克利尔沃特投资有限公司(AC和CC家庭信托)-CICPLACFT ASIC-ASIC
private string Acronym(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return value;
} else
{
var builder = new StringBuilder();
foreach(char c in value)
{
if (char.IsWhiteSpace(c) || char.IsLetterOrDigit(c))
{
builder.Append(c);
}
}
string trimmedValue = builder.ToString().Trim();
builder.Clear();
if (trimmedValue.Contains(' '))
{
for(int charIndex = 0; charIndex < trimmedValue.Length; charIndex++)
{
if (charIndex == 0)
{
builder.Append(trimmedValue[0]);
} else
{
char currentChar = trimmedValue[charIndex];
char previousChar = trimmedValue[charIndex - 1];
if (char.IsLetterOrDigit(currentChar) && char.IsWhiteSpace(previousChar))
{
builder.Append(trimmedValue[charIndex]);
}
}
}
return builder.ToString();
} else
{
return trimmedValue;
}
}
}
答案 3 :(得分:0)
我需要一个不重复的代码,所以我创建了follow方法。
如果你这样使用,你会得到
HashSet<string> idHashSet = new HashSet<string>();
for (int i = 0; i < 100; i++)
{
var eName = "China National Petroleum";
Console.WriteLine($"count:{i+1},short name:{GetIdentifierCode(eName,ref idHashSet)}");
}
方法是这样的。
/// <summary>
/// 根据英文名取其简写Code,优先取首字母,然后在每个单词中依次取字母作为Code,最后若还有重复则使用默认填充符(A)填充
/// todo 当名称为中文时,使用拼音作为取Code的源
/// </summary>
/// <param name="name"></param>
/// <param name="idHashSet"></param>
/// <returns></returns>
public static string GetIdentifierCode(string name, ref HashSet<string> idHashSet)
{
var words = name;
var fillChar = 'A';
if (string.IsNullOrEmpty(words))
{
do
{
words += fillChar.ToString();
} while (idHashSet.Contains(words));
}
//if (IsChinese)
//{
// words = GetPinYin(words);
//}
//中国石油天然气集团公司(China National Petroleum)
var sourceWord = new List<string>(words.Split(' '));
var returnWord = sourceWord.Select(c => new List<char>()).ToList();
int index = 0;
do
{
var listAddWord = sourceWord[index];
var addWord = returnWord[index];
//最后若还有重复则使用默认填充符(A)填充
if (sourceWord.All(c => string.IsNullOrEmpty(c)))
{
returnWord.Last().Add(fillChar);
continue;
}
//字符取完后跳过
else if (string.IsNullOrEmpty(listAddWord))
{
if (index == sourceWord.Count - 1)
index = 0;
else
{
index++;
}
continue;
}
if (addWord == null)
addWord = new List<char>();
string addString = string.Empty;
//字符全为大写时,不拆分
if (listAddWord.All(a => char.IsUpper(a)))
{
addWord = listAddWord.ToCharArray().ToList();
returnWord[index] = addWord;
addString = listAddWord;
}
else
{
addString = listAddWord.First().ToString();
addWord.Add(listAddWord.First());
}
listAddWord = listAddWord.Replace(addString, "");
sourceWord[index] = listAddWord;
if (index == sourceWord.Count - 1)
index = 0;
else
{
index++;
}
} while (idHashSet.Contains(string.Concat(returnWord.SelectMany(c => c))));
words = string.Concat(returnWord.SelectMany(c => c));
idHashSet.Add(words);
return words;