Учитывая строку «ThisStringHasNoSpacesButItDoesHaveCapitals», что является лучшим способом добавить пробелы перед заглавными буквами. Таким образом, конечная строка будет такой: «В этой строке нет пробелов, но есть заглавные буквы»
Вот моя попытка с RegEx
System.Text.RegularExpressions.Regex.Replace(value, "[A-Z]", " $0")
Ответы:
Регулярные выражения будут работать нормально (я даже проголосовал за ответ Мартина Браунса), но они дорогие (и лично я нахожу любой шаблон длиннее, чем пара символов, которые чрезмерно тупые)
Эта функция
Выполнит это 100 000 раз за 2 968 750 тиков, регулярное выражение займет 25 000 000 тиков (и это с скомпилированным регулярным выражением).
Это лучше, для данного значения лучше (то есть быстрее), однако, это больше кода для поддержки. «Лучше» часто является компромиссом конкурирующих требований.
Надеюсь это поможет :)
Обновление
Прошло довольно много времени с тех пор, как я посмотрел на это, и я просто понял, что время не обновлялось, так как код изменился (он только немного изменился).
На строке с Abbbbbbbbb, повторенной 100 раз (т.е. 1000 байтов), прогон 100 000 конверсий принимает функцию с ручным кодированием 4,517,177 тиков, а приведенное ниже регулярное выражение занимает 59,435,719, что делает функцию с ручным кодированием выполненной за 7,6% времени, которое занимает Regex.
Обновление 2 Будут ли приняты во внимание Сокращения? Это будет сейчас! Логика if if довольно неясна, как вы можете видеть, расширяя ее до этого ...
... совсем не помогает!
Вот оригинальный простой метод, который не беспокоится об акронимах
источник
Ваше решение имеет проблему в том, что ставит пробел перед первой буквой T, так что вы получите
Чтобы обойти это, ищите строчную букву перед ней, а затем вставьте пробел в середине:
Изменить 1:
Если вы воспользуетесь
@"(\p{Ll})(\p{Lu})"
им, то подберете и акцентированные символы.Изменить 2:
Если ваши строки могут содержать аббревиатуры, вы можете использовать это:
Таким образом, «DriveIsSCSICompatible» становится «Drive SCSI-совместимым»
источник
"([^A-Z\\s])([A-Z])"
, даже с аббревиатурами?Не тестировал производительность, но здесь в одной строке с linq:
источник
Я знаю, что это старый, но это расширение, которое я использую, когда мне нужно сделать это:
Это позволит вам использовать
MyCasedString.ToSentence()
источник
TrimStart(' ')
его, то удалит начальный пробел.SelectMany
включающую индекс, таким образом он избегает первой буквы и ненужных потенциальных накладных расходов при дополнительном вызовеTrimStart(' ')
. Роб.Я решил создать простой метод расширения, основанный на коде Binary Worrier, который будет правильно обрабатывать аббревиатуры и будет повторяться (не будет искажать уже разнесенные слова). Вот мой результат.
Вот примеры модульных тестов, которые эта функция проходит. Я добавил большинство предложенных дел Криста в этот список. Три из тех, что он не проходит (два просто римские цифры), закомментированы:
источник
Добро пожаловать в Юникод
Все эти решения по существу не соответствуют современному тексту. Вам нужно использовать что-то, что понимает дела. Так как Боб попросил другие языки, я дам пару для Perl.
Я предоставляю четыре решения, от худшего до лучшего. Только лучший всегда прав. У других есть проблемы. Вот тестовый прогон, чтобы показать вам, что работает, а что нет и где. Я использовал подчеркивание, чтобы вы могли видеть, где были помещены пробелы, и я отметил как неправильный все, что, ну, в общем, неправильно.
Кстати, почти все здесь выбрали первый путь, тот, который помечен как «Худший». Некоторые выбрали второй способ, помеченный «ОК». Но никто, кроме меня, не показал вам, как сделать «лучший» или «лучший» подход.
Вот тестовая программа с четырьмя методами:
Когда вы сможете набрать столько же, сколько и «Лучший» в этом наборе данных, вы будете знать, что сделали это правильно. До тех пор у вас нет. Никто другой здесь не сделал лучше, чем «Ок», и большинство сделали это «Худший». Я с нетерпением жду встречи с кем-то, кто отправит правильный ℂ♯ код.
Я заметил, что код подсветки StackOverflow снова жалко убог. Они делают все того же старого хромого, как (большинство, но не все) из остальных бедных подходов, упомянутых здесь. Разве давно не пора положить ASCII на отдых? Это больше не имеет смысла, и притворяться, что это все, что у тебя есть, просто неправильно. Это делает для плохого кода.
источник
Binary Worrier, я использовал предложенный вами код, и он довольно хорош, у меня есть только одно небольшое дополнение к нему:
Я добавил условие
!char.IsUpper(text[i - 1])
. Это исправило ошибку, которая приводила к тому, что что-то вроде «AverageNOX» превращалось в «Среднее NO X», что, очевидно, неправильно, так как должно отображать «Среднее NOX».К сожалению, в этом все еще есть ошибка, что если у вас есть текст «FromAStart», вы получите «From AStart».
Есть мысли по поводу исправления этого?
источник
if (char.IsUpper(text[i]) && !(char.IsUpper(text[i - 1]) && char.IsUpper(text[i + 1])))
результат: результат теста: «С самого начала», «С самого начала», «С самого начала», но вам необходимоi < text.Length - 1
в условии цикла for игнорировать последний символ и предотвращать исключение за пределы диапазона.Вот мой:
источник
<pre><code>code</code></pre>
блоке вместо синтаксиса Markdown. Не нужно отрицать его (если это был ты).Убедитесь , что вы не положить пробелы в начале строки, но которые помещая их между последовательными столицами. Некоторые из ответов здесь не касаются одного или обоих из этих пунктов. Есть и другие способы, чем регулярное выражение, но если вы предпочитаете использовать это, попробуйте это:
Знак
\B
является отрицательным\b
, поэтому он представляет собой несловесную границу. Это означает, что шаблон соответствует «Y» вXYzabc
, но не вYzabc
илиX Yzabc
. В качестве небольшого бонуса, вы можете использовать это на строке с пробелами, и она не удвоит их.источник
Это регулярное выражение помещает пробел перед каждой заглавной буквой:
Обратите внимание на пространство впереди, если «$ 1 $ 2», это то, что будет сделано.
Это результат:
источник
"([A-Z0-9])([a-z]*)"
То что у тебя работает отлично. Просто не забудьте переназначить
value
возвращаемое значение этой функции.источник
Вот как вы могли бы сделать это в SQL
источник
Вдохновленный @MartinBrown, Two Lines of Simple Regex, который разрешит ваше имя, включая ациронимы в любом месте строки.
источник
источник
источник
В Ruby через Regexp:
источник
Я взял отличное решение Кевина Страйкера и перешел на VB. Так как я заблокирован в .NET 3.5, мне также пришлось написать IsNullOrWhiteSpace. Это проходит все его испытания.
источник
Вопрос немного устарел, но в настоящее время в Nuget есть хорошая библиотека, которая делает именно это, а также многие другие преобразования в текст, читаемый человеком.
Проверьте Humanizer на GitHub или Nuget.
пример
источник
Похоже, хорошая возможность для
Aggregate
. Это разработано, чтобы быть читаемым, не обязательно особенно быстрым.источник
В дополнение к ответу Мартина Брауна у меня была проблема с числами. Например: «Location2» или «Jan22» должны быть «Location 2» и «Jan 22» соответственно.
Вот мое регулярное выражение для этого, используя ответ Мартина Брауна:
Вот пара отличных сайтов, чтобы понять, что значит каждая часть:
Анализатор регулярных выражений на основе Java (но работает для большинства .net регулярных выражений)
Анализатор действий на основе сценариев
Выше регулярное выражение не будет работать на месте сценария действия , если не заменить все
\p{Ll}
с[a-z]
, то\p{Lu}
с[A-Z]
, и\p{Nd}
с[0-9]
.источник
Вот мое решение, основанное на предложении Binary Worriers и построенном в комментариях Ричарда Приддиса, но также с учетом того, что в предоставленной строке может существовать пробел, поэтому он не добавляет пробел рядом с существующим пробелом.
источник
Для тех, кто ищет функцию C ++ и отвечает на этот же вопрос, вы можете использовать следующее. Это смоделировано после ответа, данного @Binary Worrier. Этот метод просто сохраняет Сокращения автоматически.
Тестовые строки, которые я использовал для этой функции, и результаты:
источник
C # для входной строки, которая состоит только из символов ASCII. Регулярное выражение включает в себя отрицательную ' назад , чтобы игнорировать прописной (верхний регистр) письмо , которое появляется в начале строки. Использует Regex.Replace () для возврата желаемой строки.
Также посмотрите демо regex101.com .
Ожидаемый результат:
Обновление: вот вариант, который также будет обрабатывать аббревиатуры (последовательности заглавных букв).
Также смотрите regex101.com демо и ideone.com демо .
Ожидаемый результат:
источник
Вот более полное решение, которое не ставит пробелы перед словами:
Примечание: я использовал несколько регулярных выражений (не кратко, но он также будет обрабатывать аббревиатуры и однобуквенные слова)
В :
Out :
источник
Все предыдущие ответы выглядели слишком сложными.
У меня была строка, состоящая из прописных букв и символа _, поэтому я использовал string.Replace (), чтобы сделать _, "", и использовал следующее для добавления пробела в заглавные буквы.
источник
Вдохновленный ответом Binary Worrier, я об этом подумал.
Вот результат:
Сделал тест с использованием секундомера, выполняющего 10000000 итераций и различной длины строки и комбинации.
В среднем на 50% (может быть, чуть больше) быстрее, чем ответ Binary Worrier.
источник
источник
Этот включает в себя сокращения и множественное число аббревиатур и немного быстрее, чем принятый ответ:
Проходит эти тесты:
источник
Реализация
fold
, также известная какAggregate
:В дополнение к запросу, эта реализация правильно сохраняет начальные, внутренние, конечные пробелы и сокращения, например,
источник
Простой способ добавить пробелы после строчных букв, прописных букв или цифр.
источник