Розділіть рядок на велику літеру або цифри


9

Я намагався створити трубу в машинопис, який би розділив рядок PascalCase, але було б добре, якщо це також розділиться на цифри. Я також хотів би, щоб він розділився на послідовні великі літери. У мене є ця труба, яка чудово працює, за винятком того, що вона працює лише в Chrome, а не в Firefox. Як можна досягти цього без огляду назад?

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 Amount. Цей вище вираз також розділив рядок camelCase, але це не потрібно враховувати.


.replace(/([A-Z]|\d+)/g, " $1").trim();
ібрагім махрір

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 123якому було б по-іншому працювати з вашою поточною функцією, в яку перетворюється ABC Defg 123.

Є ще невелика різниця. Твій трансформується A1B2до A 1B 2цього, до A 1 B 2якого я думаю, що це було б більш точно, чи не так.


1
Блискуче, пройшов усі мої тестові справи. Я згоден, ваша точніша. Я дійсно ціную це!
develmatik

@develmatik Радий, що це працює за бажанням, я тільки що прочитав про відмінності «Верблюда» від PascalCase :)
міхур бабла

3

Просто замініть будь-яку велику літеру [A-Z]або будь-яку послідовність цифр \d+пробілом плюс те, що ми щойно зіставили " $1". Ми пропускаємо першу букву, щоб на початку результуючого рядка не було додано пробілів, додавши відмінні знаки пошуку на початку рядка (?!^):

// ...

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.