C#从Word创建缩写

时间:2014-01-07 15:41:17

标签: c# string-interpolation

给定任何字符串,我想创建一个代表字符串的智能首字母缩略词。如果你们中的任何人使用过JIRA,他们就能很好地完成这项工作。

例如,给出单词: Phoenix 它会生成 PHX 或者给出隐私事件管理这个词会创建 PEM

我有一些代码可以完成后者:

 string.Join(string.Empty, model.Name
                .Where(char.IsLetter)
                .Where(char.IsUpper))

如果只有一个单词及其小写,则此案例不会处理。

但它没有考虑第一种情况。有任何想法吗?我正在使用C#4.5

4 个答案:

答案 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)}");
}

no repeat code

方法是这样的。

/// <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;