no-conversion
действительно означает, что буфер содержит лежащие в основе необработанные байты , а не предполагаемые символы. И когда вы меняете систему кодирования на latin-1, вы не изменяете содержимое буфера, вы просто сообщаете Emacs, что намереваетесь использовать latin-1, чтобы сохранить буфер в файл. Поэтому он жалуется на все байты, не относящиеся к ASCII, потому что latin-1 не знает, как кодировать эти байты (он только кодирует символы, которые они должны представлять, то есть кодирует их в эти байты).
Вместо этого вы хотите перезагрузить ваш файл, используя систему кодирования latin-1
(вместо no-conversion
), которую вы можете сделать с помощью C-x RET r latin-1 RET
.
Может быть, Emacs должен предложить пользователю вернуть буфер, когда буфер не модифицирован, а вы переходите с no-conversion
на что-то другое! Я предлагаю вам M-x report-emacs-bug
объяснить, почему вы нашли интерфейс запутанным.
Лично, я думаю, что Ваш метод является простым и четким, и я придерживался бы его (я думаю, что, возможно, даже написал тот же самый код где-нибудь вдоль строк).
ОБНОВЛЕНИЕ:
Как насчет этого как начальная точка?
public IEnumerable<char> MakeNice(IEnumerable<char> str)
{
foreach (var chr in str)
{
if (char.ToUpper(chr) == chr)
{
yield return ' ';
}
yield return chr;
}
}
public string MakeNiceString(string str)
{
return new string(MakeNice(str)).Trim();
}
Это делает то же как исходный код и даже избегает поколения второго (нижний регистр) строка.
var result = text.Aggregate(new StringBuilder(),
(sb, c) => (Char.IsUpper(c) ? sb.Append(' ') : sb).Append(c));
public static string ProperSpace(string text)
{
return text.Aggregate(new StringBuilder(), (sb, c) =>
{
if (Char.IsUpper(c) && sb.Length > 0)
sb.Append(" ");
sb.Append(c);
return sb;
}).ToString();
}
Как leppie, я не уверен, что это - хороший кандидат на LINQ. Вы могли вызвать его, конечно, но это не будет полезным примером. Незначительная тонкая настройка должна была бы выдержать сравнение text[i]
против lowered[i]
избегать некоторых ненужных строк - и возможно принимать значение по умолчанию сурьма к new StringBuilder(text.Length)
(или небольшое количество выше):
if (text[i] != lowered[i]) sb.Append(' ');
sb.Append(a);
Кроме этого - я оставил бы его в покое;
Я использовал бы RegularExpressions для этого случая.
public static string ProperSpace(string text)
{
var expression = new Regex("[A-Z]");
return expression.Replace(text, " $0");
}
Если Вы хотите использовать лямбду, Вы могли бы использовать:
public static string ManipulateString(string text, Func<string, string> manipulator)
{
return manipulator(text);
}
// then
var expression = new Regex("[A-Z]");
ManipulateString("DoesNotMatterHowManyWords", s => expression.Replace(text, " $0"));
Который является по существу тем же как использованием anonyous делегата
var expression = new Regex("[A-Z]");
ManipulateString("DoesNotMatterHowManyWords", delegate(s) {
return expression.Replace(text, " $0")
});
Вот способ сделать его:
string.Join("", text.Select((c, i) => (i > 0 && char.IsUpper(c)) ? " " + c : c.ToString()).ToArray());
Но я не вижу, где улучшение. Просто проверьте этот очень недавний вопрос...
РЕДАКТИРОВАНИЕ: Для тех, кто задается вопросом: да, я intentionnaly выбрал ужасное решение.
У меня есть решение Regex, которое это только в 8 раз медленнее, чем Ваша токовая петля [1], и также тяжелее считать, чем Ваше решение [2].
return Regex.Replace(text, @"(\P{Lu})(\p{Lu})", "$1 $2");
Это соответствует unicode группам символов, в этом неверхнем регистре случая, сопровождаемом верхним регистром, и затем добавляет пространство между ними. Это решение работает лучше, чем другие находящиеся в regex решения, которые только ищут [A-Z].
[1] С резервированием, что мой быстро составил тест, может высосать.
[2] Кто-либо на самом деле знает unicode группы символов без поиска с помощью Google?;)
Можно использовать существующие функции LINQ для создания этой работы, но это - вероятно, не лучший подход. Следующее выражение LINQ работало бы, но является inneficient, потому что это генерирует много дополнительных строк
public static string ProperCase(string text)
{
return text.Aggregate(
string.Empty,
(acc, c) => Char.ToLower(c) != c ? acc + " " + c.ToString() : acc + c.ToString())
.Trim();
}
Для полноценности linq (при необходимости в убеждении), Вы могли бы проверить этот вопрос.
Я думаю, что один первый шаг должен привыкнуть к точечному синтаксису и только затем идти дальше к 'sql' синтаксису. Иначе Ваши глаза просто повреждает запускаться с. Я задаюсь вопросом, не замедлила ли Microsoft внедрение linq путем продвижения синтаксиса SQL, который заставил много людей думать 'фу, код DB в моем C#'.
Что касается лямбд, попытайтесь делать некоторый код с анонимными делегатами сначала, потому что, если Вы не сделали этого, Вы действительно не поймете то, о чем суета - все.
Мне любопытно, почему простая замена регулярного выражения не была бы достаточна. Я записал один для кого-то еще, который делает точно это:
"[AI](?![A-Z]{2,})[a-z]*|[A-Z][a-z]+|[A-Z]{2,}(?=[A-Z]|$)"
Я уже опубликовал это на другом форуме маркировки здесь: http://bytes.com/topic/c-sharp/answers/864056-string-manupulation-net-c. Существует одна ошибка, которая требует сообщения regex обрезка, к которой у меня не было возможности обратиться все же, но возможно кто-то еще может отправить фиксацию для этого.
Используя шаблон замены: "0$ [пространство]", где Вы заменяете [располагают с интервалами] с фактическим пространством, сократил бы код очень.
Это обрабатывает некоторые особые случаи, которые могли бы выйти за рамки, какого Вы пытаетесь сделать, но поток доски объявлений даст Вам информацию о тех.
Править: P.S. Отличный способ начать изучать некоторые приложения LINQ состоит в том, чтобы проверить теги ГОЛЬФА и ГОЛЬФА КОДА и искать сообщения C#. Существует набор различного и более сложного использования LINQ к объектам, который должен помочь Вам распознать некоторые более полезные (?) и забавные приложения этой технологии.