Diberikan string "ThisStringHasNoSpacesButItDoesHaveCapitals" apa cara terbaik untuk menambahkan spasi sebelum huruf kapital. Jadi string akhirnya adalah "String Ini Tidak Memiliki Spasi Tapi Itu Memiliki Modal"
Ini adalah usaha saya dengan RegEx
System.Text.RegularExpressions.Regex.Replace(value, "[A-Z]", " $0")
Jawaban:
Regex akan berfungsi dengan baik (saya bahkan memilih jawaban Martin Browns), tetapi biayanya mahal (dan secara pribadi saya menemukan pola yang lebih panjang dari beberapa karakter yang tumpul)
Fungsi ini
Akan melakukannya 100.000 kali dalam 2.968.750 kutu, regex akan mengambil 25.000.000 kutu (dan thats dengan regex dikompilasi).
Lebih baik, untuk nilai yang diberikan lebih baik (yaitu lebih cepat) namun lebih banyak kode untuk dipelihara. "Lebih baik" sering berkompromi dengan persyaratan yang bersaing.
Semoga ini membantu :)
Pembaruan
Sudah lama sejak saya melihat ini, dan saya baru menyadari bahwa timing belum diperbarui karena kode berubah (hanya sedikit berubah).
Pada string dengan 'Abbbbbbbbbb' diulang 100 kali (yaitu 1.000 byte), menjalankan 100.000 konversi mengambil fungsi kode tangan 4,517.177 kutu, dan Regex di bawah ini mengambil 59.435.719 membuat fungsi kode Tangan dijalankan di 7,6% dari waktu yang dibutuhkan Regex.
Perbarui 2 Akankah Akronim diperhitungkan? Sekarang akan! Logika statemen if cukup tidak jelas, seperti yang Anda lihat memperluas ke ini ...
... tidak membantu sama sekali!
Inilah metode sederhana asli yang tidak khawatir tentang Akronim
sumber
Solusi Anda memiliki masalah karena menempatkan spasi sebelum huruf pertama T sehingga Anda dapat
Untuk menyiasati tampilan ini, huruf kecil sebelumnya juga dan kemudian masukkan spasi di tengah:
Edit 1:
Jika Anda menggunakan
@"(\p{Ll})(\p{Lu})"
akan mengambil karakter beraksen juga.Edit 2:
Jika string Anda dapat berisi akronim, Anda mungkin ingin menggunakan ini:
Jadi "DriveIsSCSICcompatible" menjadi "Drive Is SCSI Compatible"
sumber
"([^A-Z\\s])([A-Z])"
, bahkan dengan akronim?Tidak menguji kinerja, tetapi di sini sejalan dengan LINQ:
sumber
Saya tahu ini adalah yang lama, tetapi ini adalah ekstensi yang saya gunakan ketika saya perlu melakukan ini:
Ini akan memungkinkan Anda untuk menggunakan
MyCasedString.ToSentence()
sumber
TrimStart(' ')
akan menghapus ruang utama.SelectMany
yang mencakup indeks, dengan cara ini ia menghindari huruf pertama dan potensi overhead yang tidak perlu dari panggilan tambahan keTrimStart(' ')
. Rampok.Selamat datang di Unicode
Semua solusi ini pada dasarnya salah untuk teks modern. Anda perlu menggunakan sesuatu yang mengerti kasus. Karena Bob meminta bahasa lain, saya akan memberikan pasangan untuk Perl.
Saya memberikan empat solusi, mulai dari yang terburuk hingga yang terbaik. Hanya yang terbaik selalu benar. Yang lain memiliki masalah. Berikut ini adalah uji coba untuk menunjukkan kepada Anda apa yang berhasil dan yang tidak, dan di mana. Saya telah menggunakan garis bawah sehingga Anda dapat melihat di mana spasi telah diletakkan, dan saya telah menandai apa pun yang salah, yah, salah.
BTW, hampir semua orang di sini telah memilih cara pertama, yang ditandai "Terburuk". Beberapa telah memilih cara kedua, ditandai "OK". Tetapi tidak ada orang lain sebelum saya yang menunjukkan kepada Anda bagaimana melakukan pendekatan "Lebih Baik" atau "Terbaik".
Berikut adalah program pengujian dengan empat metodenya:
Saat Anda dapat skor yang sama dengan "Terbaik" pada dataset ini, Anda akan tahu bahwa Anda telah melakukannya dengan benar. Sampai saat itu, kamu belum. Tidak ada orang lain di sini yang melakukan lebih baik daripada "Ok", dan sebagian besar melakukannya "Terburuk". Saya berharap dapat melihat seseorang memposting kode ℂ♯ yang benar.
Saya perhatikan bahwa kode highlight StackOverflow bungkuk lagi. Mereka membuat semua lumpuh yang sama seperti (kebanyakan tetapi tidak semua) dari sisa pendekatan miskin yang disebutkan di sini. Bukankah sudah lama melewati ASCII untuk beristirahat? Itu tidak masuk akal lagi, dan berpura-pura semua yang Anda miliki hanyalah salah. Itu membuat kode yang buruk.
sumber
Saya mulai membuat metode ekstensi sederhana berdasarkan kode Binary Worrier's yang akan menangani akronim dengan benar, dan dapat diulangi (tidak akan memotong-motong kata yang sudah spasi). Ini hasil saya.
Berikut adalah unit-unit uji kasus yang dilewati fungsi ini. Saya menambahkan sebagian besar kasus yang disarankan tchrist ke daftar ini. Tiga dari mereka yang tidak lulus (dua hanya angka Romawi) dikomentari:
sumber
Binary Worrier, saya telah menggunakan kode yang Anda sarankan, dan itu agak bagus, saya hanya memiliki satu tambahan kecil untuk itu:
Saya telah menambahkan sebuah kondisi
!char.IsUpper(text[i - 1])
. Ini memperbaiki bug yang akan menyebabkan sesuatu seperti 'AverageNOX' diubah menjadi 'Average NO X', yang jelas-jelas salah, karena seharusnya membaca 'Average NOX'.Sayangnya ini masih memiliki bug bahwa jika Anda memiliki teks 'FromAStart', Anda akan mendapatkan 'From AStart'.
Adakah pemikiran untuk memperbaikinya?
sumber
if (char.IsUpper(text[i]) && !(char.IsUpper(text[i - 1]) && char.IsUpper(text[i + 1])))
Hasil pengujian: "Dari Mulai", "Dari Awal", "Dari Awal" tetapi Anda perlui < text.Length - 1
dalam kondisi loop untuk mengabaikan karakter terakhir dan mencegah pengecualian di luar jangkauan.Ini milik saya:
sumber
<pre><code>code</code></pre>
blok bukannya sintaks Markdown. Tidak perlu menurunkannya (jika itu kamu).Pastikan Anda tidak menempatkan spasi di awal string, tetapi Anda yang menempatkan mereka antara ibukota berturut-turut. Beberapa jawaban di sini tidak membahas satu atau kedua poin itu. Ada cara lain selain regex, tetapi jika Anda lebih suka menggunakannya, coba ini:
Ini
\B
dinegasikan\b
, sehingga mewakili batas non-kata. Ini berarti polanya cocok dengan "Y" diXYzabc
, tetapi tidak diYzabc
atauX Yzabc
. Sebagai bonus kecil, Anda dapat menggunakan ini pada string dengan spasi di dalamnya dan itu tidak akan menggandakannya.sumber
Regex ini menempatkan karakter spasi di depan setiap huruf kapital:
Pikirkan ruang di depan jika "$ 1 $ 2", inilah yang akan menyelesaikannya.
Inilah hasilnya:
sumber
"([A-Z0-9])([a-z]*)"
Apa yang Anda miliki berfungsi dengan sempurna. Ingatlah untuk menetapkan
value
kembali nilai pengembalian fungsi ini.sumber
Inilah cara Anda bisa melakukannya dalam SQL
sumber
Terinspirasi dari @MartinBrown, Two Lines of Simple Regex, yang akan menyelesaikan nama Anda, termasuk Acyronyms di mana saja di string.
sumber
sumber
sumber
Di Ruby, melalui Regexp:
sumber
Saya mengambil solusi luar biasa Kevin Strikers dan dikonversi ke VB. Karena saya terkunci di .NET 3.5, saya juga harus menulis IsNullOrWhiteSpace. Ini melewati semua tesnya.
sumber
Pertanyaannya agak lama tetapi saat ini ada perpustakaan yang bagus di Nuget yang melakukan hal ini dan juga banyak konversi lainnya ke teks yang dapat dibaca manusia.
Lihat Humanizer di GitHub atau Nuget.
Contoh
sumber
Sepertinya ini peluang bagus
Aggregate
. Ini dirancang agar dapat dibaca, tidak harus terutama cepat.sumber
Selain Jawaban Martin Brown, saya juga memiliki masalah dengan angka. Sebagai Contoh: "Location2", atau "Jan22" harus masing-masing "Location 2", dan "Jan 22".
Inilah Ekspresi Reguler saya untuk melakukan itu, menggunakan jawaban Martin Brown:
Berikut adalah beberapa situs hebat untuk mencari tahu apa arti setiap bagian juga:
Analyzer Ekspresi Reguler Berbasis Java (tetapi bekerja untuk sebagian besar .net regex's)
Penganalisa Berbasis Script Aksi
Regex di atas tidak akan berfungsi di situs skrip tindakan kecuali jika Anda mengganti semua
\p{Ll}
dengan[a-z]
,\p{Lu}
dengan[A-Z]
, dan\p{Nd}
dengan[0-9]
.sumber
Inilah solusi saya, berdasarkan saran Binary Worriers dan membangun dalam komentar Richard Priddys, tetapi juga memperhitungkan bahwa ruang putih mungkin ada dalam string yang disediakan, sehingga tidak akan menambah ruang putih di sebelah ruang putih yang ada.
sumber
Bagi siapa saja yang mencari fungsi C ++ menjawab pertanyaan yang sama, Anda dapat menggunakan yang berikut ini. Ini dimodelkan setelah jawaban yang diberikan oleh @Binary Worrier. Metode ini hanya mempertahankan Acronyms secara otomatis.
String tes yang saya gunakan untuk fungsi ini, dan hasilnya adalah:
sumber
Solusi C # untuk string input yang hanya terdiri dari karakter ASCII. The regex menggabungkan lookbehind negatif untuk mengabaikan modal (huruf) huruf yang muncul pada awal string. Menggunakan Regex.Replace () untuk mengembalikan string yang diinginkan.
Lihat juga demo regex101.com .
Output yang Diharapkan:
Pembaruan: Berikut adalah variasi yang juga akan menangani akronim (urutan huruf besar).
Juga melihat regex101.com demo dan ideone.com demo .
Output yang Diharapkan:
sumber
Berikut adalah solusi yang lebih menyeluruh yang tidak menempatkan spasi di depan kata-kata:
Catatan: Saya telah menggunakan banyak Regex (tidak ringkas tetapi juga akan menangani akronim dan kata-kata huruf tunggal)
Dalam :
Keluar :
sumber
Semua tanggapan sebelumnya tampak terlalu rumit.
Saya memiliki string yang memiliki campuran ibukota dan _ jadi digunakan, string.Replace () untuk membuat _, "" dan menggunakan yang berikut untuk menambahkan spasi pada huruf kapital.
sumber
Terinspirasi oleh jawaban Binary Worrier, saya mencoba ini.
Inilah hasilnya:
Melakukan tes menggunakan stopwatch yang menjalankan 10000000 iterasi dan berbagai panjang string serta kombinasi.
Rata-rata 50% (mungkin sedikit lebih) lebih cepat dari jawaban Binary Worrier.
sumber
sumber
Yang ini termasuk akronim dan bentuk jamak akronim dan sedikit lebih cepat dari jawaban yang diterima:
Lulus tes ini:
sumber
Implementasi dengan
fold
, juga dikenal sebagaiAggregate
:Selain permintaan, implementasi ini dengan benar menghemat spasi, akronim, spasi, dan terdepan, misalnya,
sumber
Cara sederhana untuk menambahkan spasi setelah huruf kecil, huruf besar atau digit.
sumber