การแปลงสตริงเป็นกรณีอูฐ


172

ฉันจะแปลงสตริงเป็นกรณีอูฐโดยใช้ javascript regex ได้อย่างไร

EquipmentClass nameหรือ Equipment classNameหรือequipment class nameหรือEquipment Class Name

ควรกลายเป็น: equipmentClassName.


1
ฉันทำการทดสอบjsperfของวิธีการต่างๆ ผลสรุปไม่ได้เล็กน้อย ดูเหมือนว่าจะขึ้นอยู่กับสายป้อน
yincrash


การทดสอบ jsperf ใหม่ที่มีสายอักขระที่แตกต่างกันเล็กน้อยเพื่อทดสอบและการใช้งานที่หลากหลาย: jsperf.com/camel-casing-regexp-or-character-manipulation/1 - สิ่งนี้นำฉันไปสู่ข้อสรุปว่าสำหรับกรณีทั่วไปแม้จะมี การถามคำถามนี้ของผู้ถามการแสดงออกปกติไม่ใช่สิ่งที่คุณต้องการ ไม่เพียง แต่พวกเขาจะเข้าใจได้ยากพวกเขายัง (อย่างน้อยสำหรับ Chrome เวอร์ชันปัจจุบัน) ใช้เวลาในการรันนานกว่าสองเท่า
จูลส์

คำตอบ:


239

ดูรหัสของคุณคุณสามารถทำได้ด้วยการreplaceโทรเพียงสองสาย:

function camelize(str) {
  return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
    return index === 0 ? word.toLowerCase() : word.toUpperCase();
  }).replace(/\s+/g, '');
}

camelize("EquipmentClass name");
camelize("Equipment className");
camelize("equipment class name");
camelize("Equipment Class Name");
// all output "equipmentClassName"

แก้ไข:หรือในมีเพียงหนึ่งเดียวโทรจับช่องว่างสีขาวยังอยู่ในreplaceRegExp

function camelize(str) {
  return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function(match, index) {
    if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces
    return index === 0 ? match.toLowerCase() : match.toUpperCase();
  });
}

4
รหัสที่ดีและมันก็จบลงด้วยการชนะjsperf.com/js-camelcase/5 สนใจมีส่วนร่วมในเวอร์ชันที่สามารถจัดการ (ลบ) ตัวอักษรที่ไม่ใช่ตัวอักษรได้หรือไม่ หน้าเศร้าcamelize("Let's Do It!") === "let'SDoIt!" ฉันจะลองเอง แต่กลัวว่าฉันจะเพิ่มผู้อื่นมาแทนที่
Orwellophile

2
.. เนื่องจาก non-alpha ไม่ควรส่งผลกระทบต่อกรณีนี้ฉันไม่แน่ใจว่าสามารถทำได้ดีกว่าreturn this.replace(/[^a-z ]/ig, '').replace(/(?:^\w|[A-Z]|\b\w|\s+)/g,...
Orwellophile

4
สำหรับ ES2015 + เพื่อนของฉัน: ซับหนึ่งตามรหัสข้างต้น const toCamelCase = (str) => str.replace(/(?:^\w|[A-Z]|\b\w)/g, (ltr, idx) => idx === 0 ? ltr.toLowerCase() : ltr.toUpperCase()).replace(/\s+/g, '');
tabrindle

2
ในขณะที่นี่ไม่ใช่กรณีที่ถามโดยตัวอย่างการป้อนข้อมูลทั่วไปอื่นที่คุณอาจจะเห็นคือ "EQUIPMENT CLASS NAME" ซึ่งวิธีนี้ล้มเหลว
Alexander Tsepkov

1
@EdmundReed คุณสามารถแปลงสตริงทั้งหมดเป็นตัวพิมพ์เล็กก่อนที่จะแปลงเป็นกรณีอูฐโดยผูกมัด.toLowerCase()วิธีการเช่น ใช้วิธีการแก้ปัญหาของ @ tabrindle ด้านบน:const toCamelCase = (str) => str.toLowerCase().replace(/(?:^\w|[A-Z]|\b\w)/g, (ltr, idx) => idx === 0 ? ltr.toLowerCase() : ltr.toUpperCase()).replace(/\s+/g, '');
bitfidget

103

หากใครใช้lodashก็มี_.camelCase()ฟังก์ชั่น

_.camelCase('Foo Bar');
// → 'fooBar'

_.camelCase('--foo-bar--');
// → 'fooBar'

_.camelCase('__FOO_BAR__');
// → 'fooBar'

2
คำตอบนี้ควรปรากฏขึ้นต่อไปอย่างแน่นอน Lodash จัดเตรียมชุดที่สมบูรณ์เพื่อแปลงสตริงระหว่างกรณีและปัญหาที่แตกต่างกัน
btx

55

ฉันเพิ่งจะทำสิ่งนี้:

String.prototype.toCamelCase = function(str) {
    return str
        .replace(/\s(.)/g, function($1) { return $1.toUpperCase(); })
        .replace(/\s/g, '')
        .replace(/^(.)/, function($1) { return $1.toLowerCase(); });
}

ฉันพยายามหลีกเลี่ยงการผูกมัดกันหลายคำสั่งแทนที่ สิ่งที่ฉันมี $ 1, $ 2, $ 3 ในฟังก์ชั่นของฉัน แต่การจัดกลุ่มแบบนั้นยากที่จะเข้าใจและการที่คุณพูดถึงปัญหาข้ามเบราว์เซอร์ก็เป็นสิ่งที่ฉันไม่เคยคิดมาก่อนเช่นกัน


1
ที่ดูดีสำหรับฉันและไม่มีอะไรที่น่าสงสัยเท่าที่ข้ามปัญหาเบราว์เซอร์ (ไม่ใช่ว่าฉันเป็นผู้เชี่ยวชาญหรืออะไรเลย)
Pointy

47
หากคุณจะใช้ String.prototype ทำไมไม่ใช้ 'this' แทนการส่งพารามิเตอร์ 'str'
yincrash

6
เพื่อความเข้ากันได้ของเบราว์เซอร์ที่ดีขึ้นโปรดใช้สิ่งนี้แทน str (และลบพารามิเตอร์จากการเรียกฟังก์ชัน)
João Paulo Motta

2
คุณเพียงแค่ต้องใช้แทนการส่งผ่านthis.valueOf() strอีกวิธีหนึ่ง (ในกรณีของฉัน) this.toLowerCase()เป็นสตริงอินพุตของฉันอยู่ในทุกตัวอักษรที่ไม่ได้ลดลงอย่างเหมาะสมส่วน ใช้เพียงแค่thisส่งกลับวัตถุสตริงตัวเองซึ่งเป็นอาร์เรย์ของถ่านดังนั้น TypeError ดังกล่าวข้างต้น
Draco18 ไม่ไว้วางใจ SE

2
สิ่งนี้จะคืนสิ่งที่ตรงกันข้ามกับสิ่งที่ต้องการ นี่จะส่งคืน sTRING
Awol

41

คุณสามารถใช้วิธีนี้:

function toCamelCase(str){
  return str.split(' ').map(function(word,index){
    // If it is the first word make sure to lowercase all the chars.
    if(index == 0){
      return word.toLowerCase();
    }
    // If it is not the first word only upper case the first char and lowercase the rest.
    return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
  }).join('');
}

นี่คือตัวพิมพ์ใหญ่ไม่ใช่อูฐ
nikk wong

2
กรณี Camel เป็นตัวอักษรตัวแรกของทุกคำในตัวพิมพ์ใหญ่และtoCamelCaseฟังก์ชันทำเช่นนั้น
ismnoiet

2
คุณกำลังคิดPascalCase CamelCaseสามารถเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก ในบริบทนี้มันมักจะเป็นกรณีที่ต่ำกว่าเพื่อหลีกเลี่ยงความสับสน
ดี้

1
ขอบคุณ @Kody, @ cchamberlain สำหรับความคิดเห็นที่สร้างสรรค์ของคุณให้ตรวจสอบรุ่นที่อัปเดต
ismnoiet

5
+1 สำหรับการไม่ใช้นิพจน์ทั่วไปแม้ว่าคำถามจะขอให้ใช้วิธีแก้ปัญหาก็ตาม นี่เป็นวิธีที่ชัดเจนกว่าและเป็นชัยชนะที่ชัดเจนสำหรับประสิทธิภาพ (เนื่องจากการประมวลผลนิพจน์ทั่วไปที่ซับซ้อนนั้นเป็นงานที่ยากกว่าการวนซ้ำสตริงและการรวมบิตเข้าด้วยกัน ดูjsperf.com/camel-casing-regexp-or-character-manipulation/1ที่ฉันได้นำตัวอย่างบางส่วนมาที่นี่พร้อมกับอันนี้ (และปรับปรุงตัวเองเล็กน้อยเพื่อประสิทธิภาพแม้ว่าฉันอาจจะชอบสิ่งนี้ เวอร์ชั่นเพื่อความชัดเจนในกรณีส่วนใหญ่)
จูลส์

41

ในการรับc amel C ase

ES5

var camalize = function camalize(str) {
    return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, function(match, chr)
    {
        return chr.toUpperCase();
    });
}

ES6

var camalize = function camalize(str) {
    return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());
}


ในการรับC amel S entence C aseหรือP ascal C ase

var camelSentence = function camelSentence(str) {
    return  (" " + str).toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, function(match, chr)
    {
        return chr.toUpperCase();
    });
}

หมายเหตุ:
สำหรับภาษาเหล่านั้นด้วยสำเนียง รวมÀ-ÖØ-öø-ÿกับ regex ดังนี้
.replace(/[^a-zA-ZÀ-ÖØ-öø-ÿ0-9]+(.)/g


4
คำตอบที่ดีที่สุดที่นี่ - สะอาดและรัดกุม
codeepic

5
ES6 ทำทุกอย่างให้เล็กลงสำหรับฉัน
C Bauer

@Luis เพิ่มhttps://stackoverflow.com/posts/52551910/revisionsES6 แล้วฉันยังไม่ได้ทดสอบ ฉันจะตรวจสอบและอัปเดต
smilyface

ไม่ทำงานกับคำที่มีสำเนียงjsbin.com/zayafedubo/edit?js,console
Manuel Ortiz

1
มันจะไม่ทำงานหากคุณส่งสตริงอูฐ เราต้องตรวจสอบว่าเรามีสตริงที่ได้รับการปรับให้เรียบร้อยแล้วหรือไม่
Sheikh Abdul Wahid

27

ในกรณีเฉพาะของ Scott ฉันจะไปกับ:

String.prototype.toCamelCase = function() {
    return this.replace(/^([A-Z])|\s(\w)/g, function(match, p1, p2, offset) {
        if (p2) return p2.toUpperCase();
        return p1.toLowerCase();        
    });
};

'EquipmentClass name'.toCamelCase()  // -> equipmentClassName
'Equipment className'.toCamelCase()  // -> equipmentClassName
'equipment class name'.toCamelCase() // -> equipmentClassName
'Equipment Class Name'.toCamelCase() // -> equipmentClassName

regex จะจับคู่อักขระตัวแรกถ้าเริ่มต้นด้วยตัวพิมพ์ใหญ่และตัวอักษรใด ๆ ที่ตามหลังช่องว่างคือ 2 หรือ 3 ครั้งในสตริงที่ระบุ

โดยการเพิ่มค่า regex ให้กับ/^([A-Z])|[\s-_](\w)/gมันก็จะทำให้ชื่อยัติภังค์และขีดเส้นใต้เป็นชื่อที่น่าสนใจ

'hyphen-name-format'.toCamelCase()     // -> hyphenNameFormat
'underscore_name_format'.toCamelCase() // -> underscoreNameFormat

จะเกิดอะไรขึ้นถ้ามีไฮเปอร์เทนหรือขีดล่างมากกว่า 2,3 ในสตริงเช่น. data-name, .data-product-description, .product-container__actions - ราคา,. photo-placeholder__photo
Ashwani Shukla

1
@AshwaniShukla เพื่อจัดการเครื่องหมายยัติภังค์และ / หรือขีดล่างคุณจะต้องเพิ่มตัวคูณ ( +) ลงในกลุ่มตัวละครเช่น:/^([A-Z])|[\s-_]+(\w)/g
Fredric

21
function toCamelCase(str) {
  // Lower cases the string
  return str.toLowerCase()
    // Replaces any - or _ characters with a space 
    .replace( /[-_]+/g, ' ')
    // Removes any non alphanumeric characters 
    .replace( /[^\w\s]/g, '')
    // Uppercases the first character in each group immediately following a space 
    // (delimited by spaces) 
    .replace( / (.)/g, function($1) { return $1.toUpperCase(); })
    // Removes spaces 
    .replace( / /g, '' );
}

ฉันพยายามค้นหาฟังก์ชัน JavaScript ของcamelCaseสตริงและต้องการให้แน่ใจว่าอักขระพิเศษจะถูกลบออก (และฉันมีปัญหาในการทำความเข้าใจว่าคำตอบบางข้อทำไป) สิ่งนี้ขึ้นอยู่กับคำตอบของเด็กที่มีความคิดเห็นเพิ่มเติมและการลบอักขระ $ peci & l


10

ตัวอย่างการทำงานที่เชื่อถือได้และเชื่อถือได้ที่ฉันใช้มานานหลายปี:

function camelize(text) {
    text = text.replace(/[-_\s.]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
    return text.substr(0, 1).toLowerCase() + text.substr(1);
}

อักขระที่เปลี่ยนตัวพิมพ์:

  • ยัติภังค์ -
  • ขีด _
  • ระยะเวลา .
  • ช่องว่าง

9

หากไม่จำเป็นต้องใช้ regexp คุณอาจต้องการดูรหัสต่อไปนี้ที่ฉันทำเมื่อนานมาแล้วสำหรับTwinkle :

String.prototype.toUpperCaseFirstChar = function() {
    return this.substr( 0, 1 ).toUpperCase() + this.substr( 1 );
}

String.prototype.toLowerCaseFirstChar = function() {
    return this.substr( 0, 1 ).toLowerCase() + this.substr( 1 );
}

String.prototype.toUpperCaseEachWord = function( delim ) {
    delim = delim ? delim : ' ';
    return this.split( delim ).map( function(v) { return v.toUpperCaseFirstChar() } ).join( delim );
}

String.prototype.toLowerCaseEachWord = function( delim ) {
    delim = delim ? delim : ' ';
    return this.split( delim ).map( function(v) { return v.toLowerCaseFirstChar() } ).join( delim );
}

ฉันไม่ได้ทำการทดสอบประสิทธิภาพและรุ่น regexp อาจจะเร็วกว่าหรือไม่


โดยเฉลี่ยเร็วขึ้น 5 เท่าหากคุณต้องการเพียง 1 คำjsbin.com/wuvagenoka/edit?html,js,output
Omu

8

วิธีES6ของฉัน:

const camelCase = str => {
  let string = str.toLowerCase().replace(/[^A-Za-z0-9]/g, ' ').split(' ')
                  .reduce((result, word) => result + capitalize(word.toLowerCase()))
  return string.charAt(0).toLowerCase() + string.slice(1)
}

const capitalize = str => str.charAt(0).toUpperCase() + str.toLowerCase().slice(1)

let baz = 'foo bar'
let camel = camelCase(baz)
console.log(camel)  // "fooBar"
camelCase('foo bar')  // "fooBar"
camelCase('FOO BAR')  // "fooBar"
camelCase('x nN foo bar')  // "xNnFooBar"
camelCase('!--foo-¿?-bar--121-**%')  // "fooBar121"

แล้วชื่ออย่าง Jean-Pierre ล่ะ?
Max Alexander Hanna


5

lodashสามารถทำเคล็ดลับได้อย่างแน่นอนและดี:

var _ = require('lodash');
var result = _.camelCase('toto-ce héros') 
// result now contains "totoCeHeros"

แม้ว่าlodashอาจเป็นห้องสมุด "ใหญ่" (~ 4kB) แต่ก็มีฟังก์ชั่นมากมายที่ปกติคุณจะใช้เป็นตัวอย่างหรือสร้างเอง


มีโมดูล npm พร้อมกับแต่ละฟังก์ชั่นบ้านพักดังนั้นคุณไม่จำเป็นต้องนำเข้าไลบรารี "ใหญ่" ทั้งหมด: npmjs.com/package/lodash.camelcase
gion_13

5

นี่คือหนึ่งในการทำงาน:

const camelCaseIt = string => string.toLowerCase().trim().split(/[.\-_\s]/g).reduce((string, word) => string + word[0].toUpperCase() + word.slice(1));

มันแยกสตริงที่ต่ำกว่าตามรายการของตัวละครที่มีให้ใน RegExp [.\-_\s](เพิ่มมากขึ้นภายใน []!) และส่งกลับอาร์เรย์คำ จากนั้นจะลดอาเรย์ของสตริงเป็นสตริงของคำที่ต่อกันด้วยตัวอักษรตัวใหญ่ตัวแรก เนื่องจากการลดไม่มีค่าเริ่มต้นมันจะเริ่มอักษรตัวพิมพ์ใหญ่ตัวแรกที่ขึ้นต้นด้วยคำที่สอง

ถ้าคุณต้องการ PascalCase เพียงเพิ่มสตริงว่างเริ่มต้น,'')เพื่อวิธีการลด


3

ตามวิธีการที่อ่านได้ของ @ Scott การปรับแต่งเล็กน้อย

// แปลงสตริงเป็น camelCase
var toCamelCase = ฟังก์ชั่น (str) {
  ส่งคืน str.toLowerCase ()
    .replace (/ ['"] / g,' ')
    .replace (/ \ W + / g, '')
    .replace (/ (.) / g, ฟังก์ชั่น ($ 1) {ส่งคืน $ 1.toUpperCase ();})
    .replace (/ / g, '');
}

3

คำตอบของ Scott ดัดแปลงเล็กน้อย:

toCamelCase = (string) ->
  string
    .replace /[\s|_|-](.)/g, ($1) -> $1.toUpperCase()
    .replace /[\s|_|-]/g, ''
    .replace /^(.)/, ($1) -> $1.toLowerCase()

ตอนนี้มันแทนที่ '-' และ '_' ด้วย


3

การเปลี่ยนลำดับทั้งหมด 14 รายการด้านล่างให้ผลลัพธ์เดียวกันกับ "equipmentClassName"

String.prototype.toCamelCase = function() {
  return this.replace(/[^a-z ]/ig, '')  // Replace everything but letters and spaces.
    .replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, // Find non-words, uppercase letters, leading-word letters, and multiple spaces.
      function(match, index) {
        return +match === 0 ? "" : match[index === 0 ? 'toLowerCase' : 'toUpperCase']();
      });
}

String.toCamelCase = function(str) {
  return str.toCamelCase();
}

var testCases = [
  "equipment class name",
  "equipment class Name",
  "equipment Class name",
  "equipment Class Name",
  "Equipment class name",
  "Equipment class Name",
  "Equipment Class name",
  "Equipment Class Name",
  "equipment className",
  "equipment ClassName",
  "Equipment ClassName",
  "equipmentClass name",
  "equipmentClass Name",
  "EquipmentClass Name"
];

for (var i = 0; i < testCases.length; i++) {
  console.log(testCases[i].toCamelCase());
};


ใช่. ฉันชอบการใช้วิธีต้นแบบที่มีสตริงมากกว่าฟังก์ชั่น ช่วยด้วยการผูกมัด
russellmania

3

คุณสามารถใช้วิธีนี้:

String.prototype.toCamelCase = function(){
  return this.replace(/\s(\w)/ig, function(all, letter){return letter.toUpperCase();})
             .replace(/(^\w)/, function($1){return $1.toLowerCase()});
};

console.log('Equipment className'.toCamelCase());


ตัวอย่างนี้แสดงวิธีใช้ฟังก์ชันสองฟังก์ชันอื่นในเมธอด replace
Chang Hoon Lee

3

เพราะคำถามนี้ต้องการคำตอบอีกข้อ ...

ฉันลองวิธีแก้ไขปัญหาก่อนหน้าหลายข้อและทุกข้อมีข้อบกพร่องอย่างใดอย่างหนึ่ง บางคนไม่ได้ลบเครื่องหมายวรรคตอน บางคนไม่จัดการกรณีที่มีตัวเลข บางคนไม่ได้จัดการเครื่องหมายวรรคตอนหลายอย่างในแถว

a1 2bไม่มีของพวกเขาจัดการสตริงเหมือน ไม่มีแบบแผนที่กำหนดไว้อย่างชัดเจนสำหรับกรณีนี้ แต่คำถามสแต็คโอเวอร์โฟลว์อื่น ๆแนะนำให้แยกตัวเลขด้วยเครื่องหมายขีดล่าง

ฉันสงสัยว่านี่เป็นคำตอบที่มีประสิทธิภาพมากที่สุด (สาม regex ผ่านสตริงมากกว่าหนึ่งหรือสอง) แต่มันผ่านการทดสอบทั้งหมดที่ฉันสามารถคิด ถึงจะซื่อสัตย์ฉันไม่สามารถจินตนาการถึงกรณีที่คุณแปลงอูฐเป็นจำนวนมากซึ่งการแสดงนั้นสำคัญ

(ฉันเพิ่มสิ่งนี้เป็นแพ็กเกจ npmนอกจากนี้ยังมีพารามิเตอร์บูลีนเผื่อเลือกเพื่อส่งคืน Pascal Case แทน Camel Case)

const underscoreRegex = /(?:[^\w\s]|_)+/g,
    sandwichNumberRegex = /(\d)\s+(?=\d)/g,
    camelCaseRegex = /(?:^\s*\w|\b\w|\W+)/g;

String.prototype.toCamelCase = function() {
    if (/^\s*_[\s_]*$/g.test(this)) {
        return '_';
    }

    return this.replace(underscoreRegex, ' ')
        .replace(sandwichNumberRegex, '$1_')
        .replace(camelCaseRegex, function(match, index) {
            if (/^\W+$/.test(match)) {
                return '';
            }

            return index == 0 ? match.trimLeft().toLowerCase() : match.toUpperCase();
        });
}

กรณีทดสอบ (ล้อเล่น)

test('Basic strings', () => {
    expect(''.toCamelCase()).toBe('');
    expect('A B C'.toCamelCase()).toBe('aBC');
    expect('aB c'.toCamelCase()).toBe('aBC');
    expect('abc      def'.toCamelCase()).toBe('abcDef');
    expect('abc__ _ _def'.toCamelCase()).toBe('abcDef');
    expect('abc__ _ d_ e _ _fg'.toCamelCase()).toBe('abcDEFg');
});

test('Basic strings with punctuation', () => {
    expect(`a'b--d -- f.h`.toCamelCase()).toBe('aBDFH');
    expect(`...a...def`.toCamelCase()).toBe('aDef');
});

test('Strings with numbers', () => {
    expect('12 3 4 5'.toCamelCase()).toBe('12_3_4_5');
    expect('12 3 abc'.toCamelCase()).toBe('12_3Abc');
    expect('ab2c'.toCamelCase()).toBe('ab2c');
    expect('1abc'.toCamelCase()).toBe('1abc');
    expect('1Abc'.toCamelCase()).toBe('1Abc');
    expect('abc 2def'.toCamelCase()).toBe('abc2def');
    expect('abc-2def'.toCamelCase()).toBe('abc2def');
    expect('abc_2def'.toCamelCase()).toBe('abc2def');
    expect('abc1_2def'.toCamelCase()).toBe('abc1_2def');
    expect('abc1 2def'.toCamelCase()).toBe('abc1_2def');
    expect('abc1 2   3def'.toCamelCase()).toBe('abc1_2_3def');
});

test('Oddball cases', () => {
    expect('_'.toCamelCase()).toBe('_');
    expect('__'.toCamelCase()).toBe('_');
    expect('_ _'.toCamelCase()).toBe('_');
    expect('\t_ _\n'.toCamelCase()).toBe('_');
    expect('_a_'.toCamelCase()).toBe('a');
    expect('\''.toCamelCase()).toBe('');
    expect(`\tab\tcd`.toCamelCase()).toBe('abCd');
    expect(`
ab\tcd\r

-_

|'ef`.toCamelCase()).toBe(`abCdEf`);
});

ทำงานได้ดีเยี่ยมขอบคุณ จัดการกับสถานการณ์อื่น ๆ อีกมากมายเมื่อเปรียบเทียบกับคำตอบเบื้องต้นอื่น ๆ
sean2078

2

มีวิธีแก้ปัญหาของฉันคือ:

const toCamelWord = (word, idx) =>
  idx === 0 ?
  word.toLowerCase() :
  word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();

const toCamelCase = text =>
  text
  .split(/[_-\s]+/)
  .map(toCamelWord)
  .join("");

console.log(toCamelCase('User ID'))


1

วิธีนี้ดูเหมือนว่าจะตอบได้ดีกว่าคำตอบส่วนใหญ่ที่นี่มันค่อนข้างแฮ็กเล็กน้อยไม่มีการแทนที่ไม่มี regex เพียงแค่สร้างสตริงใหม่ที่ camelCase

String.prototype.camelCase = function(){
    var newString = '';
    var lastEditedIndex;
    for (var i = 0; i < this.length; i++){
        if(this[i] == ' ' || this[i] == '-' || this[i] == '_'){
            newString += this[i+1].toUpperCase();
            lastEditedIndex = i+1;
        }
        else if(lastEditedIndex !== i) newString += this[i].toLowerCase();
    }
    return newString;
}

1

นี่เป็นการสร้างคำตอบด้วย CMS โดยการลบอักขระที่ไม่ใช่ตัวอักษรใด ๆรวมถึงขีดล่างซึ่ง\wไม่ได้ลบออก

function toLowerCamelCase(str) {
    return str.replace(/[^A-Za-z0-9]/g, ' ').replace(/^\w|[A-Z]|\b\w|\s+/g, function (match, index) {
        if (+match === 0 || match === '-' || match === '.' ) {
            return ""; // or if (/\s+/.test(match)) for white spaces
        }
        return index === 0 ? match.toLowerCase() : match.toUpperCase();
    });
}

toLowerCamelCase("EquipmentClass name");
toLowerCamelCase("Equipment className");
toLowerCamelCase("equipment class name");
toLowerCamelCase("Equipment Class Name");
toLowerCamelCase("Equipment-Class-Name");
toLowerCamelCase("Equipment_Class_Name");
toLowerCamelCase("Equipment.Class.Name");
toLowerCamelCase("Equipment/Class/Name");
// All output e

1

ตัวอูฐตัวบน ("TestString") ไปที่ตัวเล็กตัวอูฐ ("testString") โดยไม่ต้องใช้ regex (ลองเผชิญหน้ากัน regex นั้นมันชั่วร้าย):

'TestString'.split('').reduce((t, v, k) => t + (k === 0 ? v.toLowerCase() : v), '');

2
พารามิเตอร์อักขระเดียวยังคงชั่วร้ายเล็กน้อยในแง่ของการอ่าน
danwellman

1

ฉันสิ้นสุดการกำหนดวิธีแก้ปัญหาเชิงรุกเล็กน้อย:

function toCamelCase(str) {
  const [first, ...acc] = str.replace(/[^\w\d]/g, ' ').split(/\s+/);
  return first.toLowerCase() + acc.map(x => x.charAt(0).toUpperCase() 
    + x.slice(1).toLowerCase()).join('');
}

ตัวอักษรด้านบนนี้จะลบอักขระที่ไม่ใช่ตัวอักษรและตัวเลขทั้งหมดและส่วนที่เป็นตัวพิมพ์เล็กของคำที่จะเป็นตัวพิมพ์ใหญ่เช่น

  • Size (comparative) => sizeComparative
  • GDP (official exchange rate) => gdpOfficialExchangeRate
  • hello => hello

1
function convertStringToCamelCase(str){
    return str.split(' ').map(function(item, index){
        return index !== 0 
            ? item.charAt(0).toUpperCase() + item.substr(1) 
            : item.charAt(0).toLowerCase() + item.substr(1);
    }).join('');
}      

1

นี่คือคำแนะนำของฉัน:

function toCamelCase(string) {
  return `${string}`
    .replace(new RegExp(/[-_]+/, 'g'), ' ')
    .replace(new RegExp(/[^\w\s]/, 'g'), '')
    .replace(
      new RegExp(/\s+(.)(\w+)/, 'g'),
      ($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}`
    )
    .replace(new RegExp(/\s/, 'g'), '')
    .replace(new RegExp(/\w/), s => s.toLowerCase());
}

หรือ

String.prototype.toCamelCase = function() {
  return this
    .replace(new RegExp(/[-_]+/, 'g'), ' ')
    .replace(new RegExp(/[^\w\s]/, 'g'), '')
    .replace(
      new RegExp(/\s+(.)(\w+)/, 'g'),
      ($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}`
    )
    .replace(new RegExp(/\s/, 'g'), '')
    .replace(new RegExp(/\w/), s => s.toLowerCase());
};

กรณีทดสอบ:

describe('String to camel case', function() {
  it('should return a camel cased string', function() {
    chai.assert.equal(toCamelCase('foo bar'), 'fooBar');
    chai.assert.equal(toCamelCase('Foo Bar'), 'fooBar');
    chai.assert.equal(toCamelCase('fooBar'), 'fooBar');
    chai.assert.equal(toCamelCase('FooBar'), 'fooBar');
    chai.assert.equal(toCamelCase('--foo-bar--'), 'fooBar');
    chai.assert.equal(toCamelCase('__FOO_BAR__'), 'fooBar');
    chai.assert.equal(toCamelCase('!--foo-¿?-bar--121-**%'), 'fooBar121');
  });
});

1

ฉันรู้ว่านี่เป็นคำตอบเก่า แต่สิ่งนี้จัดการทั้งช่องว่างและ _ (lodash)

function toCamelCase(s){
    return s
          .replace(/_/g, " ")
          .replace(/\s(.)/g, function($1) { return $1.toUpperCase(); })
          .replace(/\s/g, '')
          .replace(/^(.)/, function($1) { return $1.toLowerCase(); });
}

console.log(toCamelCase("Hello world");
console.log(toCamelCase("Hello_world");

// Both print "helloWorld"

ขอบคุณสำหรับการนี้ แต่มีที่ดูเหมือนจะเป็นจรจัด"ใน.replace(/_/g", " ")ที่ผิดพลาดสาเหตุรวบรวม?
Crashalot


0

แก้ไข : ตอนนี้ทำงานใน IE8 โดยไม่มีการเปลี่ยนแปลง

แก้ไข : ผมอยู่ในชนกลุ่มน้อยเกี่ยวกับสิ่งที่ CamelCase จริงเป็น (ตัวละครชั้นนำตัวพิมพ์เล็กกับพิมพ์ใหญ่.) ชุมชนส่วนใหญ่เชื่อว่าตัวพิมพ์เล็กชั้นนำเป็นตัวอูฐและเงินทุนชั้นนำเป็นตัวพิมพ์ใหญ่ ฉันสร้างสองฟังก์ชันที่ใช้รูปแบบ regex เท่านั้น :) ดังนั้นเราใช้คำศัพท์แบบครบวงจรฉันได้เปลี่ยนท่าทางของฉันเพื่อให้ตรงกับคนส่วนใหญ่


ทั้งหมดที่ฉันเชื่อว่าคุณต้องการคือ regex เดียวในทั้งสองกรณี:

var camel = " THIS is camel case "
camel = $.trim(camel)
    .replace(/[^A-Za-z]/g,' ') /* clean up non-letter characters */
    .replace(/(.)/g, function(a, l) { return l.toLowerCase(); })
    .replace(/(\s.)/g, function(a, l) { return l.toUpperCase(); })
    .replace(/[^A-Za-z\u00C0-\u00ff]/g,'');
// Returns "thisIsCamelCase"

หรือ

var pascal = " this IS pascal case "
pascal = $.trim(pascal)
  .replace(/[^A-Za-z]/g,' ') /* clean up non-letter characters */
  .replace(/(.)/g, function(a, l) { return l.toLowerCase(); })
  .replace(/(^.|\s.)/g, function(a, l) { return l.toUpperCase(); })
  .replace(/[^A-Za-z\u00C0-\u00ff]/g,'');
// Returns "ThisIsPascalCase"

ในฟังก์ชั่น: คุณจะสังเกตเห็นว่าในฟังก์ชั่นเหล่านี้การแทนที่จะทำการสลับใด ๆ ที่ไม่ใช่ az ด้วยช่องว่างเทียบกับสตริงว่าง นี่คือการสร้างขอบเขตคำสำหรับการใช้อักษรตัวพิมพ์ใหญ่ "hello-MY # world" -> "HelloMyWorld"

// remove \u00C0-\u00ff] if you do not want the extended letters like é
function toCamelCase(str) {
    var retVal = '';

    retVal = $.trim(str)
      .replace(/[^A-Za-z]/g, ' ') /* clean up non-letter characters */
      .replace(/(.)/g, function (a, l) { return l.toLowerCase(); })
      .replace(/(\s.)/g, function (a, l) { return l.toUpperCase(); })
      .replace(/[^A-Za-z\u00C0-\u00ff]/g, '');

    return retVal
}

function toPascalCase(str) {
    var retVal = '';

    retVal = $.trim(str)
      .replace(/[^A-Za-z]/g, ' ') /* clean up non-letter characters */
      .replace(/(.)/g, function (a, l) { return l.toLowerCase(); })
      .replace(/(^.|\s.)/g, function (a, l) { return l.toUpperCase(); })
      .replace(/[^A-Za-z\u00C0-\u00ff]/g, '');

    return retVal
}

หมายเหตุ:

  • ฉันออกจาก A-Za-z กับการเพิ่มแฟล็ก insensitivity case (i)ในรูปแบบ (/ [^ AZ] / ig) เพื่อให้อ่านง่าย
  • ใช้งานได้ในIE8 (บางรายซึ่งใช้ IE8 อีกต่อไป) การใช้เครื่องมือ dev (F12) ที่ฉันได้ทดสอบใน IE11, IE10, IE9, IE8, IE7 และ IE5 ทำงานในโหมดเอกสารทั้งหมด
  • นี่จะเป็นตัวอักษรตัวแรกของสตริงที่ถูกต้องซึ่งเริ่มต้นด้วยหรือไม่มีช่องว่าง

สนุก


ตัวอักษรตัวแรกยังคงเป็นตัวพิมพ์ใหญ่?
Dave Clarke

ใช่. มันจะเป็นตัวพิมพ์ใหญ่ในกรณีที่มันต่ำกว่าหรือสูงกว่าที่จะเริ่มต้น
โจจอห์นสตัน

2
นั่นไม่ใช่กรณีของอูฐ - และไม่ตรงกับสิ่งที่ OP ร้องขอ?
Dave Clarke

หวังว่าการแก้ไขนี้จะให้ผลลัพธ์ที่ OP ต้องการ สำหรับชีวิตของฉันฉันไม่รู้ว่าการลงคะแนนเสียงนั้นมีไว้เพื่ออะไร ไม่ตอบ OP ... ที่จะทำ :)
Joe Johnston

1
ฉันเชื่อว่า "PascalCase" เป็นสิ่งที่เราเรียกว่า camelCase ด้วยเงินทุนชั้นนำ
Ted Morin

0

ฉันคิดว่ามันน่าจะทำงานได้ ..

function cammelCase(str){
    let arr = str.split(' ');
    let words = arr.filter(v=>v!='');
    words.forEach((w, i)=>{
        words[i] = w.replace(/\w\S*/g, function(txt){
            return txt.charAt(0).toUpperCase() + txt.substr(1);
        });
    });
    return words.join('');
}

0

อย่าใช้ String.prototype.toCamelCase () เนื่องจาก String.prototypes เป็นแบบอ่านอย่างเดียวคอมไพเลอร์ js ส่วนใหญ่จะให้คำเตือนนี้

เช่นเดียวกับฉันคนที่รู้ว่าสตริงจะมีเพียงช่องว่างเดียวเท่านั้นที่สามารถใช้วิธีที่ง่ายกว่า:

let name = 'test string';

let pieces = name.split(' ');

pieces = pieces.map((word, index) => word.charAt(0)[index===0 ? 'toLowerCase' :'toUpperCase']() + word.toLowerCase().slice(1));

return pieces.join('');

ขอให้มีความสุขในวันนี้ :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.