Нормализация строк
-
03-07-2019 - |
Вопрос
Я пишу некоторый код, который должен выполнять нормализацию строк, я хочу превратить данную строку в верблюжье представление (ну, по крайней мере, в лучшем предположении).Пример:
"the quick brown fox" => "TheQuickBrownFox"
"the_quick_brown_fox" => "TheQuickBrownFox"
"123The_quIck bROWN FOX" => "TheQuickBrownFox"
"the_quick brown fox 123" => "TheQuickBrownFox123"
"thequickbrownfox" => "Thequickbrownfox"
Я думаю, вы должны быть в состоянии уловить идею из этих примеров.Я хочу избавиться от всего особенный символы (', ", !, @, ., и т.д.), писать каждое слово заглавными буквами (слова обозначаются пробелом, _ или -) и любые ведущие цифры удалено (конечное / внутреннее в порядке, но это требование не является жизненно важным, в зависимости от сложности на самом деле).
Я пытаюсь понять, каков был бы наилучший способ достичь этого.Мое первое предположение было бы связано с регулярным выражением, но мои навыки использования регулярных выражений в лучшем случае плохи, так что я действительно не знаю, с чего начать.
Моя другая идея состояла бы в том, чтобы зациклить и проанализировать данные, скажем, разбить их на слова, проанализируйте каждый из них и перестроьте строку таким образом.
Или есть другой способ, которым я мог бы это сделать?
Решение
Как насчет простого решения, использующего Строки.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();
}
}
}
Другие советы
Это регулярное выражение соответствует всем словам.Затем мы 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]*"
, Я полагаю - но я это не проверял.
Любое решение, включающее сопоставление определенных символов, может плохо работать с некоторыми кодировками символов, особенно если используется представление Unicode, которое содержит десятки пробелов, тысячи "символов", тысячи знаков препинания, тысячи "букв" и т.д.Было бы лучше, когда это вообще возможно, использовать встроенные функции, поддерживающие Юникод.Что касается того, что такое "особый символ", ну, вы могли бы решить, основываясь на Категории в Юникоде.Например, он включал бы "Пунктуацию", но включал бы ли он "Символы"?
ToLower(), isLetter() и т.д. Должны быть в порядке и учитывать все возможные буквы в Юникоде.Сопоставление с тире и косой чертой, вероятно, должно учитывать некоторые из десятков символов пробела и тире в Юникоде.
Ты мог бы надевайте рубиновые тапочки на работу :)
def camelize str
str.gsub(/^[^a-zA-z]*/, '').split(/[^a-zA-Z0-9]/).map(&:capitalize).join
end
подумал, что было бы забавно попробовать, и вот что у меня получилось:
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();
}
}
}