Podziel ciąg na wielką literę lub cyfry


9

Próbowałem utworzyć potok w maszynie do pisania, który podzieliłby łańcuch PascalCase, ale byłoby miło, gdyby to również podzieliło się na cyfry. Chciałbym również, aby dzieliła się na kolejne duże litery. Mam ten potok, który działa świetnie, z tym że działa tylko w Chrome, a nie w Firefoxie, najwyraźniej tylko Chrome obsługuje przeglądanie wstecz. Jak można to osiągnąć bez odwrotu?

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

Na przykład ciąg ANet15Amountpowinien zostać przekształcony w A Net 15 Amount. Powyższe wyrażenie regularne również podzieli ciąg camelCase, ale nie jest to konieczne do rozważenia.


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

2
@ibrahimmahrir (?!^)([A-Z]|\d+)unika pierwszego miejsca i nie wymaga przycinania.
ctwheels

Odpowiedzi:


6

Co powiesz na dopasowanie bardziej prostym wzorem takim jak ten i połączenie ze spacją.

let str = `ANet15Amount`;

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

console.log(camel);

Najpierw myślałem po prostu [A-Z][a-z]*|\d+, ale to złamie np ABCDefg123w A B C Defg 123której byłaby inna roboczego do bieżącej funkcji, które zmieniają się ABC Defg 123.

Nadal jest mała różnica. Twoja przemienia A1B2się w A 1B 2tę i A 1 B 2tam, gdzie myślę, że ta będzie bardziej dokładna, prawda?


1
Świetnie, przeszedłem wszystkie moje testy. Zgadzam się, twój jest dokładniejszy. Bardzo to doceniam!
develmatik

@develmatik Cieszę się, że działa zgodnie z życzeniem, właśnie przeczytałem o różnicach między Camel a PascalCase :)
bobble bubble

3

Po prostu zamień dowolną wielką literę [A-Z]lub sekwencję cyfr \d+spacją plus to, co właśnie dopasowaliśmy " $1". Pomijamy pierwszą literę, aby żadne spacje nie były dodawane na początku wynikowego ciągu, dodając ujemny wynik na początku łańcucha (?!^):

// ...

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

Przykład:



2

Myślę, że to zależy od konwencji ciągu, co może zwiększyć złożoność

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.