วิธีการแปลง“ camelCase” เป็น“ Camel Case”?


174

ฉันได้พยายามที่จะได้รับคำสั่ง regex JavaScript เพื่อเปิดสิ่งที่ชอบ"thisString"เข้า"This String"แต่ที่ใกล้เคียงที่สุดผมเคยถูกใช้แทนที่จดหมายที่ส่งผลให้ในสิ่งที่ต้องการหรือ"Thi String" "This tring"ความคิดใด ๆ

ชี้แจงฉันสามารถจัดการความเรียบง่ายของพะวงจดหมายฉันแค่ไม่เป็นที่แข็งแกร่งกับ RegEx และแยก"somethingLikeThis"ออกเป็น"something Like This"เป็นที่ที่ฉันมีปัญหา



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

อืมมันไม่ได้เป็นของคำถาม แต่ผลลัพธ์อาจเหมือนกัน หรือนั่นไม่ใช่สิ่งที่คุณต้องการจะทำ? อธิบายเพิ่มเติมหรือไม่
superfro

สำหรับการฝึก regex ฉันแนะนำ RegExr หรือ Expresso เพื่อทดสอบและเพียงแค่ดูคำถาม regex ทั้งหมดใน SO และลองตอบคำถามเหล่านั้น Regex ไม่ใช่สิ่งที่ง่ายที่สุดในโลก แต่เพียงจำไว้ว่าถ้า regex ของคุณทำให้คุณสับสนแล้วแยกมันออกเป็นชิ้น ๆ
josh.trow

คำตอบ:


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

แสดง

This String Is Good


1
คนดีแยกมันออกมา เพียงจำคำแนะนำของ Bobince: stackoverflow.com/questions/1732348/…
josh.trow

คุณแน่ใจหรือไม่ว่าเข้ากันได้กับ IE? เพิ่งลองใน IETester7 และได้รับข้อผิดพลาด
Strongriley

3
การเพิ่ม: หากคุณมีตัวพิมพ์ใหญ่ทั้งหมดที่คุณต้องการเก็บไว้ด้วยกันคุณสามารถเปลี่ยน regex แรกเป็น "/ ([AZ] [az]) /"
jackfrster

2
"This" -> "This" (พื้นที่ส่วนนำหน้าที่ไม่ต้องการ) อาจเปลี่ยนเป็น: str.slice (0, 1) .toUpperCase () + str.slice (1) .replace (/ ([AZ]) / g, '$ 1')
Mark Vayngrib

1
@ColdCerberus คุณสามารถใช้: str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() );มันจะแปลงuserIDเป็นUser IDและมันจะแปลงuserIDFieldเป็นUser ID Field
Eugene Mala

87

ฉันมีความสนใจที่ไม่ได้ใช้งานในเรื่องนี้โดยเฉพาะอย่างยิ่งในการจัดการลำดับของเมืองหลวงเช่นใน xmlHTTPRequest ฟังก์ชั่นที่ระบุไว้จะผลิต "คำขอ Xml HTTP" หรือ "Xml HTTPRequest" เหมืองสร้าง "คำขอ Xml HTTP"

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(); })
}

นอกจากนี้ยังมีรุ่น String.prototype ในส่วนสำคัญ


สามารถทำได้ด้วยการแทนที่ 2 สาย:str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() )
Eugene Mala

22

สิ่งนี้สามารถสรุปได้อย่างชัดเจนด้วย regex lookahead ( การสาธิตสด ):

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

(ฉันคิดว่าgจำเป็นต้องมีการตั้งค่าสถานะ (ส่วนกลาง) แต่ผิดปกติพอสมควรในกรณีนี้

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

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

mapวิธีอาร์เรย์เป็นคุณลักษณะ ES5 แต่คุณยังคงสามารถใช้งานได้ในเบราว์เซอร์สูงอายุที่มีโค้ดบางส่วนจาก MDC หรือคุณสามารถวนซ้ำองค์ประกอบองค์ประกอบโดยใช้การforวนซ้ำ


ฟังก์ชั่นแรกแยกมัน แต่ไม่ PascalCase คำแรก ฟังก์ชั่นที่สองล้มเหลวในกรณีที่ไม่มี camelCased (เช่น: 'id')
Dementic

16

ฉันคิดว่านี่น่าจะสามารถจัดการตัวอักษรตัวพิมพ์ใหญ่ต่อเนื่องเช่นเดียวกับ camelCase ง่าย ๆ

ตัวอย่างเช่น: someVariable => someVariable แต่ ABCCode! = ABC Code

regex ด้านล่างทำงานกับตัวอย่างของคุณ แต่ยังเป็นตัวอย่างทั่วไปของการแสดงตัวย่อใน 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"

คุณสามารถปรับตามข้างบนเพื่อใช้ประโยชน์อักขระตัวแรก


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

spacecamel ( 'somethingLikeThis')

// มูลค่าที่ส่งคืน: บางสิ่งเช่นนี้


1
ทำได้ดีนี่! นี่คือสิ่งที่ฉันต้องการฉันต้องการแยกเช่น: DiscoveryChannel และ HBO คำตอบอื่น ๆ ให้ฉัน Discovery Channel และ HBO แต่คำตอบของคุณทำเคล็ดลับสำหรับฉันเพราะ HBO ยังคงอยู่เหมือนเดิมขอบคุณ!
AJS


4

โซลูชันที่จัดการกับตัวเลขเช่นกัน:

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 + ' ';
          }
       )
   }

ทดสอบที่นี่ [JSFiddle ไม่มีห้องสมุด ไม่ได้ลอง IE]; ควรจะค่อนข้างมั่นคง


0

หากคุณไม่สนใจเกี่ยวกับเบราว์เซอร์รุ่นเก่า (หรือไม่คำนึงถึงการใช้ฟังก์ชันลดการย้อนกลับสำหรับพวกเขา) สิ่งนี้สามารถแยกสตริงได้แม้กระทั่งเช่น 'xmlHTTPRequest' (แต่แน่นอนว่าไลค์ของ

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(' ');
}

0

รุ่นของฉัน

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"

ฉันใช้ฟังก์ชั่นนี้วนซ้ำบน 3000 บรรทัดและมีช่องว่างเหล่านั้นต่อหน้าทุกบรรทัดที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่
Dominik Domanski

0

ลองใช้วิธีแก้ปัญหาที่นี่ -

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;

-5

ไม่ใช่ regex แต่มีประโยชน์ที่จะรู้เทคนิคธรรมดาและเก่าเช่นนี้

var origString = "thisString";
var newString = origString.charAt(0).toUpperCase() + origString.substring(1);

5
ไม่คำถามคือ "thisString" ถึง "สตริงนี้" (มีช่องว่าง) ไม่ใช่ "ThisString"
Pete Kirkham

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