Bagaimana cara mengubah "camelCase" menjadi "Camel Case"?

174

Saya sudah mencoba untuk mendapatkan perintah regex JavaScript untuk mengubah sesuatu "thisString"menjadi "This String"tetapi yang paling dekat saya adalah mengganti surat, menghasilkan sesuatu seperti "Thi String"atau "This tring". Ada ide?

Untuk memperjelas saya bisa menangani kesederhanaan memanfaatkan surat, aku hanya tidak sekuat dengan regex, dan membelah "somethingLikeThis"ke "something Like This"mana aku mengalami kesulitan.

Seorang Penyihir Melakukannya
sumber
6
Bagaimana ini duplikat dari itu. Yang dilakukan adalah memanfaatkan karakter pertama dalam sebuah string, tidak ada yang mendekati apa yang ingin saya lakukan.
Penyihir Melakukannya
Hmm ini bukan duplikat dari pertanyaan, tetapi hasilnya mungkin sama. Atau bukankah itu yang ingin Anda lakukan? Lebih rumit?
superf
Untuk latihan regex saya sarankan RegExr atau Expresso untuk menguji dan hanya melihat semua pertanyaan regex pada SO dan mencoba menjawabnya. Regex bukanlah hal yang paling sederhana di dunia, tetapi ingatlah bahwa jika regex Anda membingungkan ANDA maka bagi dan bagi menjadi beberapa bagian.
josh.trow

Jawaban:

399
"thisStringIsGood"
    // insert a space before all caps
    .replace(/([A-Z])/g, ' $1')
    // uppercase the first character
    .replace(/^./, function(str){ return str.toUpperCase(); })

menampilkan

This String Is Good

Vincent Robert
sumber
1
Pria yang baik, membaginya. Ingat saja saran Bobince: stackoverflow.com/questions/1732348/…
josh.trow
Apakah Anda yakin ini kompatibel dengan IE? Baru saja mencoba di IETester7 & mendapat kesalahan.
strongriley
3
Juga menambahkan: jika Anda memiliki akronim semua huruf besar yang ingin Anda pertahankan, Anda dapat mengubah regex pertama menjadi "/ ([AZ] [az]) /"
jackfrster
2
"Ini" -> "Ini" (ruang awalan yang tidak diinginkan). Mungkin ubah ke: str.slice (0, 1) .toUpperCase () + str.slice (1) .replace (/ ([AZ]) / g, '$ 1')
Mark Vayngrib
1
@ColdCerberus Anda dapat menggunakan: str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() );Ini akan dikonversi userIDke User ID, dan bahkan akan dikonversi userIDFieldkeUser ID Field
Eugene Mala
87

Saya memiliki minat kosong dalam hal ini, khususnya dalam menangani urutan modal, seperti di xmlHTTPRequest. Fungsi-fungsi yang terdaftar akan menghasilkan "Permintaan HTTP Xml" atau "Permintaan HTT Xml", milik saya menghasilkan "Permintaan HTTP Xml".

function unCamelCase (str){
    return str
        // insert a space between lower & upper
        .replace(/([a-z])([A-Z])/g, '$1 $2')
        // space before last upper in a sequence followed by lower
        .replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
        // uppercase the first character
        .replace(/^./, function(str){ return str.toUpperCase(); })
}

Ada juga versi String.prototype di inti .

Matt Wiebe
sumber
Hal yang sama dapat dicapai dengan 2 panggilan pengganti:str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() )
Eugene Mala
22

Ini dapat dilakukan secara ringkas dengan regex lookahead ( live demo ):

function splitCamelCaseToString(s) {
    return s.split(/(?=[A-Z])/).join(' ');
}

(Saya pikir gbendera (global) itu perlu, tetapi anehnya, tidak ada dalam kasus khusus ini.)

Menggunakan lookahead with splitmemastikan bahwa huruf kapital yang cocok tidak dikonsumsi dan menghindari berurusan dengan ruang terkemuka jika UpperCamelCase adalah sesuatu yang perlu Anda tangani. Untuk mengubah huruf besar dari huruf pertama, Anda dapat menggunakan:

function splitCamelCaseToString(s) {
    return s.split(/(?=[A-Z])/).map(function(p) {
        return p.charAt(0).toUpperCase() + p.slice(1);
    }).join(' ');
}

The mapMetode array fitur ES5, tapi Anda masih dapat menggunakannya di browser lama dengan beberapa kode dari MDC . Atau, Anda dapat beralih di atas elemen array menggunakan forloop.

PleaseStand
sumber
Fungsi pertama membaginya, tetapi tidak PascalCase kata pertama. Fungsi kedua gagal pada case yang tidak ada camel. (mis: 'id')
Dementic
16

Saya pikir ini harus dapat menangani karakter huruf besar berturut-turut serta camelCase sederhana.

Misalnya: someVariable => someVariable, tetapi ABCCode! = Kode ABC.

Regex di bawah ini berfungsi pada contoh Anda tetapi juga contoh umum mewakili singkatan di camcelCase.

"somethingLikeThis"
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace(/([A-Z])([a-z])/g, ' $1$2')
    .replace(/\ +/g, ' ') => "something Like This"

"someVariableWithABCCode"
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace(/([A-Z])([a-z])/g, ' $1$2')
    .replace(/\ +/g, ' ') => "some Variable With ABC Code"

Anda juga dapat menyesuaikan seperti di atas untuk menggunakan huruf kapital karakter pertama.

thegreenpizza
sumber
10
function spacecamel(s){
    return s.replace(/([a-z])([A-Z])/g, '$1 $2');
}

spacecamel ('somethingLikeThis')

// nilai yang dikembalikan: sesuatu Seperti Ini

kennebec
sumber
1
Yang bagus! ini adalah persis apa yang saya butuhkan saya ingin membagi misalnya: DiscoveryChannel dan HBO jawaban lain memberi saya Discovery Channel dan HBO, tetapi jawaban Anda melakukan trik untuk saya karena HBO tetap utuh terima kasih!
AJS
8

Lodash menangani ini dengan baik_.startCase()

Lawrence Chang
sumber
4

Solusi yang menangani angka juga:

function capSplit(str){
   return str.replace
      ( /(^[a-z]+)|[0-9]+|[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z]|[0-9])/g
      , function(match, first){
          if (first) match = match[0].toUpperCase() + match.substr(1);
          return match + ' ';
          }
       )
   }

Diuji di sini [JSFiddle, tidak ada perpustakaan. Tidak mencoba IE]; harus cukup stabil.

SamGoody
sumber
0

Jika Anda tidak peduli dengan peramban yang lebih lama (atau tidak keberatan menggunakan fungsi penurunan cadangan untuknya), ini dapat membagi string genap seperti 'xmlHTTPRequest' (tapi tentu saja yang seperti 'XMLHTTPRequest' tidak dapat).

function splitCamelCase(str) {
        return str.split(/(?=[A-Z])/)
                  .reduce(function(p, c, i) {
                    if (c.length === 1) {
                        if (i === 0) {
                            p.push(c);
                        } else {
                            var last = p.pop(), ending = last.slice(-1);
                            if (ending === ending.toLowerCase()) {
                                p.push(last);
                                p.push(c);
                            } else {
                                p.push(last + c);
                            }
                        }
                    } else {
                        p.push(c.charAt(0).toUpperCase() + c.slice(1));
                    }
                    return p;
                  }, [])
                  .join(' ');
}
Daniel Fernández Espinoza
sumber
0

Versi saya

function camelToSpace (txt) {
  return txt
    .replace(/([^A-Z]*)([A-Z]*)([A-Z])([^A-Z]*)/g, '$1 $2 $3$4')
    .replace(/ +/g, ' ')
}
camelToSpace("camelToSpaceWithTLAStuff") //=> "camel To Space With TLA Stuff"
Pykiss
sumber
Saya menerapkan fungsi ini dalam loop pada 3000 baris, dan mendapatkan ruang-ruang itu di depan setiap baris yang dimulai dengan modal
Dominik Domanski
0

Coba solusi ini di sini -

var value = "myCamelCaseText";
var newStr = '';
for (var i = 0; i < value.length; i++) {
  if (value.charAt(i) === value.charAt(i).toUpperCase()) {
    newStr = newStr + ' ' + value.charAt(i)
  } else {
    (i == 0) ? (newStr += value.charAt(i).toUpperCase()) : (newStr += value.charAt(i));
  }
}
return newStr;
M3ghana
sumber
-5

Bukan regex, tetapi berguna untuk mengetahui teknik biasa dan lama seperti ini:

var origString = "thisString";
var newString = origString.charAt(0).toUpperCase() + origString.substring(1);
rampok
sumber
5
tidak, pertanyaannya adalah "thisString" menjadi "This String" (dengan spasi) bukan "ThisString"
Pete Kirkham
@rob Bagaimana Anda memberi jarak antara "ini" dan "Tali"?
ThunderBird