Нормализация строки - PullRequest
0 голосов
/ 03 марта 2009

Я пишу некоторый код, который должен выполнить нормализацию строки, я хочу превратить данную строку в представление в случае верблюда (ну, по крайней мере, по крайней мере). Пример:

"the quick brown fox" => "TheQuickBrownFox"
"the_quick_brown_fox" => "TheQuickBrownFox"
"123The_quIck bROWN FOX" => "TheQuickBrownFox"
"the_quick brown fox 123" => "TheQuickBrownFox123"
"thequickbrownfox" => "Thequickbrownfox"

Я думаю, вы должны быть в состоянии понять идею из этих примеров. Я хочу вычеркнуть все специальные символы (', ",!, @,. И т. Д.), Использовать заглавные буквы в каждом слове (слова определяются пробелом, _ или -) и любые начальные числа отброшено (трейлинг / внутренний в порядке, но это требование не является жизненно важным, в зависимости от сложности на самом деле).

Я пытаюсь понять, что было бы лучшим способом достичь этого. Мое первое предположение было бы с регулярным выражением, но мои навыки регулярных выражений в лучшем случае плохие, поэтому я не знаю, с чего начать.

Моя другая идея состояла бы в том, чтобы зациклить и проанализировать данные, скажем, разбить их на слова , проанализировать каждое из них и перестроить строку таким образом.

Или есть другой способ, которым я мог бы пойти по этому поводу?

Ответы [ 5 ]

3 голосов
/ 03 марта 2009

Как насчет простого решения, использующего Strings.StrConv в пространстве имен Microsoft.VisualBasic? (Не забудьте добавить ссылку на проект в Microsoft.VisualBasic):

using System;
using VB = Microsoft.VisualBasic;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(VB.Strings.StrConv("QUICK BROWN", VB.VbStrConv.ProperCase, 0));
            Console.ReadLine();
        }
    }
}
1 голос
/ 03 марта 2009

Вы можете носить на работе рубиновые тапочки :)

def camelize str
  str.gsub(/^[^a-zA-z]*/, '').split(/[^a-zA-Z0-9]/).map(&:capitalize).join
end
1 голос
/ 03 марта 2009

Любое решение, предусматривающее сопоставление определенных символов, может не работать с некоторыми кодировками символов, особенно если используется представление Unicode, содержащее десятки пробелов, тысячи «символов», тысячи знаков пунктуации, тысячи «букв» и т. д. Было бы лучше по возможности использовать встроенные функции, поддерживающие Юникод. Что касается «специального символа», то вы можете решить, основываясь на категориях Unicode . Например, это будет включать «Пунктуация», но будет ли это «Символы»?

ToLower (), IsLetter () и т. Д. Должны быть в порядке и учитывать все возможные буквы в Unicode. Сопоставление с дефисами и дефисами, вероятно, должно учитывать некоторые из десятков пробелов и символов дефиса в Unicode.

1 голос
/ 03 марта 2009

Это регулярное выражение соответствует всем словам. Затем мы Aggregate обрабатываем их методом, который использует первые символы в верхнем регистре, а ToLower оставшуюся часть строки.

Regex regex = new Regex(@"[a-zA-Z]*", RegexOptions.Compiled);

private string CamelCase(string str)
{
    return regex.Matches(str).OfType<Match>().Aggregate("", (s, match) => s + CamelWord(match.Value));
}

private string CamelWord(string word)
{
    if (string.IsNullOrEmpty(word))
        return "";

    return char.ToUpper(word[0]) + word.Substring(1).ToLower();
}

Этот метод, кстати, игнорирует числа. Чтобы добавить их, вы можете изменить регулярное выражение на @"[a-zA-Z]*|[0-9]*", я полагаю - но я не проверял его.

0 голосов
/ 03 марта 2009

думал, что было бы интересно попробовать, вот что я придумал:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();
            string sentence = "123The_quIck bROWN FOX1234";

            sentence = sentence.ToLower();

            char[] s = sentence.ToCharArray();

            bool atStart = true;
            char pChar = ' ';

            char[] spaces = { ' ', '_', '-' };
            char a;
            foreach (char c in s)
            {
                if (atStart && char.IsDigit(c)) continue;

                if (char.IsLetter(c))
                {
                    a = c;
                    if (spaces.Contains(pChar))
                        a = char.ToUpper(a);
                    sb.Append(a);
                    atStart = false;
                }
                else if(char.IsDigit(c))
                {
                    sb.Append(c);
                }
                pChar = c;
            }

            Console.WriteLine(sb.ToString());
            Console.ReadLine();
        }
    }
}
...