แปลงยัติภังค์เป็นกรณีอูฐ (camelCase)


146

ด้วย regex (ฉันถือว่า) หรือวิธีอื่นฉันจะแปลงสิ่งต่าง ๆ เช่น:

marker-imageหรือmy-example-settingไปหรือmarkerImagemyExampleSetting

ฉันคิดว่าจะแยก-แล้วแปลงดัชนีของ hypen +1 นั้นเป็นตัวพิมพ์ใหญ่ แต่ดูเหมือนว่าสกปรกและหวังว่าจะช่วย regex ที่จะทำให้โค้ดสะอาด

ไม่มี jQuery ...


1
ซ้ำกันอย่างแน่นอนของJavaScript RegExp $ 1 เป็นตัวพิมพ์ใหญ่
mplungjan

7
เป็นจริง แต่ฉันค้นหาและไม่เคยพบอาจเป็นเพราะชื่อคลุมเครือ รหัสแนะนำให้คงไว้ซึ่งสิ่งนี้เพื่อให้ผู้คนสามารถค้นหาคำตอบได้จริง "RegExp $ 1 เป็นตัวพิมพ์ใหญ่" ... ไม่มีใครหามันได้นอกเสียจากว่าพวกเขารู้จัก Regex IMO แล้ว
Oscar Godson

นั่นแก้ไขได้ง่าย ฉันเพิ่งแก้ไขชื่อ
mplungjan

ดังนั้นการตัดและวางโซลูชั่นจะทำให้ฉันได้รับคำตอบที่ยอมรับ: |
mplungjan

มีวิธีทำตรงข้ามแน่นอนหรือไม่
Pavan

คำตอบ:


258

ลองสิ่งนี้:

var camelCased = myString.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });

การแสดงออกปกติจะตรงกับ-iในและจับเท่านั้นmarker-image iนี่คือตัวพิมพ์ใหญ่ในฟังก์ชันการเรียกกลับและแทนที่


53
นี่คือสิ่งที่ตรงกันข้าม:myString.replace(/([a-z][A-Z])/g, function (g) { return g[0] + '-' + g[1].toLowerCase() });
Cyril N.

ฉันคิดว่าพารามิเตอร์ควรเปลี่ยนชื่อเป็น "m" เช่น "match" หนึ่งสามารถเขียนได้อย่างรวดเร็วเช่น: myString.replace(/-([a-z])/i, function (i) { return i[1].toUpperCase() });
โปรแกรม

8
เป็นความคิดที่ดีที่จะทำให้ regex ของคุณแข็งแกร่งขึ้นโดยการเพิ่มiแฟล็ก หากไม่มีรูปแบบของคุณจะขาด "ส่วนที่เป็นตัวพิมพ์ใหญ่" (จะไม่ถูกเปลี่ยนเป็น "ตัวพิมพ์ใหญ่ส่วน") นอกจากนี้ฉันเองชอบความสามารถในการอ่านที่ดีขึ้นของพารามิเตอร์หลายตัว แต่เห็นได้ชัดว่าเป็นเรื่องของสไตล์ .replace( /-([a-z])/gi, function ( $0, $1 ) { return $1.toUpperCase(); } );ทั้งหมดในทุกฉันไปกับ
hashchange

หากต้องการเพิ่มในกรณีนี้หากคุณต้องการแยกคำอูฐกับช่องว่างด้วยเช่นกันรายการต่อไปนี้จะใช้งานได้:var camelCased = myString.replace(/(-+|\s+)\w/g, function (g) { return g[1].toUpperCase(); });
wolfram77

@ wolfram77 คุณใส่อักขระขีดคั่น / อักขระหลายตัวใน regexp จากนั้นพิมพ์อักขระตัวที่สองของการจับคู่ขึ้นมาซึ่งหมายความว่าอักขระตัวที่สองนั้นเป็นช่องว่างหรือเส้นประ วิธีการเกี่ยวกับเรื่องนี้: var camelCased = myString.replace(/(-+|\s+)\w/g, function (g) { return g[g.length - 1].toUpperCase(); });?
trysis

44

นี่เป็นหนึ่งในสาธารณูปโภคที่ยอดเยี่ยมที่Lodashเสนอถ้าคุณรู้แจ้งและนำไปรวมไว้ในโครงการของคุณ

var str = 'my-hyphen-string';
str = _.camelCase(str);
// results in 'myHyphenString'

14

คุณสามารถรับไฮเปอร์และตัวละครถัดไปและแทนที่ด้วยอักขระตัวพิมพ์ใหญ่:

var str="marker-image-test";
str.replace(/-([a-z])/g, function (m, w) {
    return w.toUpperCase();
});

3
ดี - ฉันไปด้วยวิธีนี้ แต่ ES6 จะเป็น >> str.replace (/ - ([az]) / g, (x, up) => up.toUpperCase ())
ConorLuddy

13

นี่คือฟังก์ชัน camelCase รุ่นของฉัน:

var camelCase = (function () {
    var DEFAULT_REGEX = /[-_]+(.)?/g;

    function toUpper(match, group1) {
        return group1 ? group1.toUpperCase() : '';
    }
    return function (str, delimiters) {
        return str.replace(delimiters ? new RegExp('[' + delimiters + ']+(.)?', 'g') : DEFAULT_REGEX, toUpper);
    };
})();

มันจัดการกรณีขอบทั้งหมดต่อไปนี้:

  • ดูแลทั้งขีดล่างและขีดกลางโดยค่าเริ่มต้น (กำหนดค่าได้ด้วยพารามิเตอร์ที่สอง)
  • สตริงที่มีอักขระ Unicode
  • สตริงที่ลงท้ายด้วยยัติภังค์หรือขีดล่าง
  • สตริงที่มีเครื่องหมายขีดกลางหรือเครื่องหมายขีดล่าง

นี่คือลิงค์สำหรับทดสอบสด: http://jsfiddle.net/avKzf/2/

นี่คือผลลัพธ์จากการทดสอบ:

  • อินพุต: "ab-cd-ef" ผลลัพธ์: "abCdEf"
  • อินพุต: "ab-cd-ef-" ผลลัพธ์: "abCdEf"
  • อินพุต: "ab-cd-ef--" ผลลัพธ์: "abCdEf"
  • อินพุต: "ab-cd - ef--" ผลลัพธ์: "abCdEf"
  • อินพุต: "--ab-cd - ef--" ผลลัพธ์: "AbCdEf"
  • อินพุต: "--ab-cd -__- ef--" ผลลัพธ์: "AbCdEf"

ขอให้สังเกตว่าสตริงที่ขึ้นต้นด้วยตัวคั่นจะส่งผลให้ตัวอักษรตัวพิมพ์ใหญ่ที่จุดเริ่มต้น หากนั่นไม่ใช่สิ่งที่คุณคาดหวังคุณสามารถใช้ lcfirst ได้ตลอดเวลา นี่คือครั้งแรกของฉันถ้าคุณต้องการ:

function lcfirst(str) {
    return str && str.charAt(0).toLowerCase() + str.substring(1);
}

4

สิ่งนี้ไม่ได้ส่งเสียงร้องสำหรับRegExpฉัน ส่วนตัวฉันพยายามหลีกเลี่ยงการแสดงออกปกติเมื่อวิธีการสตริงและอาร์เรย์ที่เรียบง่ายจะพอเพียง:

let upFirst = word => 
  word[0].toUpperCase() + word.toLowerCase().slice(1)

let camelize = text => {
  let words = text.split(/[-_]/g) // ok one simple regexp.
  return words[0].toLowerCase() + words.slice(1).map(upFirst)
}

camelize('marker-image') // markerImage

1

นี่คือตัวเลือกอื่นที่รวมคำตอบสองสามข้อไว้ที่นี่และทำให้เป็นวิธีบนสตริง:

if (typeof String.prototype.toCamel !== 'function') {
  String.prototype.toCamel = function(){
    return this.replace(/[-_]([a-z])/g, function (g) { return g[1].toUpperCase(); })
  };
}

ใช้แบบนี้:

'quick_brown'.toCamel(); // quickBrown
'quick-brown'.toCamel(); // quickBrown


1

คุณสามารถใช้camelcaseจาก NPM

npm install --save camelcase

const camelCase = require('camelcase');
camelCase('marker-image'); // => 'markerImage';
camelCase('my-example-setting'); // => 'myExampleSetting';

0

ใช้เวลาอีก

ใช้เมื่อ ...

var string = "hyphen-delimited-to-camel-case"
or
var string = "snake_case_to_camel_case"


function toCamelCase( string ){
  return string.toLowerCase().replace(/(_|-)([a-z])/g, toUpperCase );
}

function toUpperCase( string ){
  return string[1].toUpperCase();
}

Output: hyphenDelimitedToCamelCase

0

เป็นไปได้ที่จะใช้ indexOf พร้อมการเรียกซ้ำสำหรับภารกิจนั้น

input some-foo_sd_dsd-weqe
output someFooSdDsdWeqe

การเปรียบเทียบ ::: วัดเวลาดำเนินการสำหรับสคริปต์ที่แตกต่างกันสองรายการ:

$ node camelCased.js
someFooSdDsdWeqe
test1: 2.986ms
someFooSdDsdWeqe
test2: 0.231ms

รหัส:

console.time('test1');
function camelCased (str) {

        function check(symb){

            let idxOf = str.indexOf(symb);
            if (idxOf === -1) {
                return str;
            }

            let letter = str[idxOf+1].toUpperCase();
            str = str.replace(str.substring(idxOf+1,idxOf+2), '');
            str = str.split(symb).join(idxOf !== -1 ? letter : '');

            return camelCased(str);
        }       

        return check('_') && check('-');

    }

console.log(camelCased ('some-foo_sd_dsd-weqe'));
console.timeEnd('test1');



console.time('test2');

    function camelCased (myString){
     return myString.replace(/(-|\_)([a-z])/g, function (g) { return  g[1].toUpperCase(); });
   }


console.log(camelCased ('some-foo_sd_dsd-weqe'));
console.timeEnd('test2');

0

เพียงแค่เวอร์ชันที่มีการตั้งค่าสถานะสำหรับการวนซ้ำและไม่มี Regex:

function camelCase(dash) { 

  var camel = false;
  var str = dash;
  var camelString = '';

  for(var i = 0; i < str.length; i++){
    if(str.charAt(i) === '-'){
      camel = true;

    } else if(camel) {
      camelString += str.charAt(i).toUpperCase();
      camel = false;
    } else {
      camelString += str.charAt(i);
    }
  } 
  return camelString;
}

0

นี่คือการดำเนินการของฉัน (เพียงเพื่อทำให้มือสกปรก)

/**
 * kebab-case to UpperCamelCase
 * @param {String} string
 * @return {String}
 */
function toUpperCamelCase(string) {
  return string
    .toLowerCase()
    .split('-')
    .map(it => it.charAt(0).toUpperCase() + it.substr(1))
    .join('');
}

0

ใช้สิ่งนี้หากคุณอนุญาตตัวเลขในสตริงของคุณ

เห็นได้ชัดว่าชิ้นส่วนที่ขึ้นต้นด้วยตัวเลขจะไม่ถูกพิมพ์ใหญ่ แต่อาจมีประโยชน์ในบางสถานการณ์

function fromHyphenToCamelCase(str) {
  return str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase())
}

function fromHyphenToCamelCase(str) {
  return str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase())
}

const str1 = "category-123";
const str2 = "111-222";
const str3 = "a1a-b2b";
const str4 = "aaa-2bb";

console.log(`${str1} => ${fromHyphenToCamelCase(str1)}`);
console.log(`${str2} => ${fromHyphenToCamelCase(str2)}`);
console.log(`${str3} => ${fromHyphenToCamelCase(str3)}`);
console.log(`${str4} => ${fromHyphenToCamelCase(str4)}`);

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