Pisahkan string pada huruf besar atau angka

9

Saya mencoba untuk membuat pipa dalam naskah yang akan membagi string PascalCase, tetapi akan lebih baik jika ini juga akan terpecah pada digit juga. Saya juga ingin membaginya dengan huruf kapital berturut-turut. Saya memiliki pipa ini, yang berfungsi dengan baik, kecuali hanya berfungsi di Chrome dan bukan Firefox, ternyata hanya Chrome yang mendukung tampilan belakang. Bagaimana bisa melakukan ini tanpa melihat ke belakang?

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

Jadi misalnya string ANet15Amountharus diubah menjadi A Net 15 Amount. Regex ini di atas juga akan memisahkan string camelCase, tetapi itu tidak perlu dipertimbangkan.

develmatik
sumber
.replace(/([A-Z]|\d+)/g, " $1").trim();
ibrahim mahrir
2
@ibrahimmahrir (?!^)([A-Z]|\d+)menghindari ruang pertama dan tidak perlu langsing.
ctwheels

Jawaban:

6

Bagaimana kalau cocok dengan pola yang lebih mendasar seperti ini dan bergabung dengan ruang.

let str = `ANet15Amount`;

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

console.log(camel);

Pertama saya pikir dari hanya [A-Z][a-z]*|\d+tapi ini akan mematahkan misalnya ABCDefg123ke A B C Defg 123mana akan berbeda kerja untuk fungsi Anda saat ini, yang transformasi ke ABC Defg 123.

Masih ada sedikit perbedaan. Anda berubah A1B2menjadi A 1B 2dan yang ini ke A 1 B 2tempat saya pikir yang ini akan lebih akurat, bukan.

gelembung berbandul
sumber
1
Cemerlang, lulus semua test case saya. Saya setuju, milik Anda lebih akurat. Saya sangat menghargai itu!
develmatik
@develmatik Senang itu berfungsi seperti yang diinginkan, saya baru saja membaca tentang perbedaan Camel ke PascalCase :)
bobble bubble
3

Ganti saja huruf besar [A-Z]atau urutan angka apa pun \d+dengan spasi plus apa yang baru saja kami cocokkan " $1". Kami melewatkan huruf pertama sehingga tidak ada ruang yang akan ditambahkan pada awal string yang dihasilkan dengan menambahkan lookahead negatif pada awal string (?!^):

// ...

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

Contoh:

ibrahim mahrir
sumber
2

Mencoba [A-Z]?[a-z]+|[A-Z]|[0-9]+

  • 0 atau 1 huruf besar langsung diikuti oleh 1 atau lebih huruf kecil
  • atau 1 huruf besar
  • atau 1 atau lebih digit

Uji dalam generator: https://regex101.com/r/uBO0P5/1

tony
sumber
2

Saya kira itu tergantung pada konvensi string yang dapat meningkatkan kompleksitas

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

1O1
sumber