แยกสตริงบนตัวพิมพ์ใหญ่หรือตัวเลข


9

ฉันพยายามที่จะสร้างไพพ์ใน typescript ที่จะแยกสตริง PascalCase แต่มันจะดีถ้ามันจะแบ่งเป็นตัวเลขด้วยเช่นกัน ฉันต้องการให้แยกตามตัวอักษรพิมพ์ใหญ่ต่อเนื่อง ฉันมีไพพ์นี้ซึ่งใช้งานได้ดียกเว้นว่าใช้งานได้เฉพาะใน Chrome และไม่ใช่ Firefox เท่านั้น Chrome เท่านั้นที่รองรับการมองย้อนหลัง จะทำสิ่งนี้ให้สำเร็จโดยไม่มองย้อนกลับไปได้อย่างไร

transform(value: string): string {
        let extracted = '';
        if (!value) {
            return extracted;
        }

        const regExSplit = value
            .split(new RegExp('(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[0-9])(?=[A-Z][a-z])|(?<=[a-zA-Z])(?=[0-9])'));
        for (let i = 0; i < regExSplit.length; i++) {
            if (i !== regExSplit.length - 1) {
                extracted += `${regExSplit[i]} `;
            } else {
                extracted += regExSplit[i];
            }
        }

        return extracted;
    }

ดังนั้นสำหรับตัวอย่างเช่นสตริงควรจะเปลี่ยนเป็นANet15Amount A Net 15 AmountRegex ด้านบนนี้จะแยกสตริง camelCase ด้วย แต่ก็ไม่จำเป็นที่จะต้องพิจารณา


.replace(/([A-Z]|\d+)/g, " $1").trim();
ibrahim mahrir

2
@ibrahimmahrir (?!^)([A-Z]|\d+)หลีกเลี่ยงช่องว่างแรกและไม่จำเป็นต้องตัดแต่ง
ctwheels

คำตอบ:


6

วิธีการจับคู่โดยรูปแบบพื้นฐานเพิ่มเติมเช่นนี้และเข้าร่วมกับช่องว่าง

let str = `ANet15Amount`;

let camel = str.match(/[A-Z]+(?![a-z])|[A-Z]?[a-z]+|\d+/g).join(' ');

console.log(camel);

ครั้งแรกที่ฉันคิดว่าเพียง[A-Z][a-z]*|\d+แต่นี้จะทำลายเช่นABCDefg123ลงไปซึ่งจะเป็นการทำงานที่แตกต่างกันเพื่อฟังก์ชั่นในปัจจุบันของคุณที่จะแปลงA B C Defg 123ABC Defg 123

ยังคงมีความแตกต่างเล็กน้อย ของคุณเปลี่ยนA1B2ไปA 1B 2และอันนี้เป็นA 1 B 2ที่ที่ฉันคิดว่าอันนี้จะแม่นยำมากขึ้นใช่มั้ย


1
ยอดเยี่ยมผ่านการทดสอบทั้งหมดของฉัน ฉันเห็นด้วยคุณมีความแม่นยำมากขึ้น ฉันซาบซึ้งจริงๆ!
develmatik

@develmatik ดีใจที่มันได้ผลตามที่ต้องการฉันแค่อ่านเกี่ยวกับความแตกต่างของ Camel to PascalCase :)
bobble bubble

3

เพียงแค่เปลี่ยนอักษรตัวพิมพ์ใหญ่ใด ๆ[A-Z]หรือลำดับใด ๆ ของตัวเลขที่มีพื้นที่เป็นบวกสิ่งที่เราเป็นเพียงแค่การจับคู่\d+ " $1"เราข้ามตัวอักษรตัวแรกเพื่อไม่ให้มีการเพิ่มช่องว่างที่จุดเริ่มต้นของสตริงผลลัพธ์โดยการเพิ่ม lookahead เชิงลบที่จุดเริ่มต้นของสตริง(?!^):

// ...

return value.replace(/(?!^)([A-Z]|\d+)/g, " $1");

ตัวอย่าง:


2

ลอง [A-Z]?[a-z]+|[A-Z]|[0-9]+

  • 0 หรือ 1 ตัวอักษรตัวพิมพ์ใหญ่โดยตรงตามด้วยตัวอักษรตัวเล็ก 1 ตัวหรือมากกว่า
  • หรือ 1 ตัวอักษรตัวพิมพ์ใหญ่
  • หรือ 1 หรือมากกว่าหลัก

ทดสอบเครื่องกำเนิดไฟฟ้า: https://regex101.com/r/uBO0P5/1


2

ฉันเดามันขึ้นอยู่กับอนุสัญญาของสายซึ่งอาจเพิ่มความซับซ้อน

// here 'TIMES' & 'with' are seperated (example 2)
const str = 'SplittingStringsIsFunTimesA100000aaaTIMESwithFollowUp';

// here 'TIMES' & 'With' are seperated (exmpaple 3)
const str2 = 'SplittingStringsIsFunTimesA100000aaaTIMESWithCAPITAL5FollowUp';


// 1. USING REGEX - MATCH
console.log(
  '1. USING REGEX:\n',
  str
  .match(/(\d+|[a-z]+|[A-Z][a-z]*)/g)
  .join(' ')
);


// 2. USING REGEX - MATCH (KEEP ALL CAPITAL CHARS)
console.log(
  '2. USING REGEX (GROUP ALL):\n',
  str
  .match(/(\d+|[a-z]+|([A-Z]([A-Z]+|[a-z]*)))/g)
  .join(' ')
);

// 3. USING REGEX - MATCH (KEEP CAPITAL CHARS BUT LAST)
console.log(
  '3. USING REGEX (GROUP BUT LAST):\n',
  str2
  .match(/(\d+|[a-z]+|([A-Z]([a-z]+|([A-Z]+(?![a-z]))?)))/g)
  .join(' ')
);


// 4. USING SPLIT - FILTER
console.log(
  '4. USING SPLIT:\n',
  str2
  .split(/(\d+|[A-Z][a-z]*)/)
  .filter(v => v !== '')
  .join(' ')
);

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