Teilen Sie eine Zeichenfolge auf einen Großbuchstaben oder Zahlen

9

Ich habe versucht, eine Pipe in Typoskript zu erstellen, die eine PascalCase-Zeichenfolge aufteilt, aber es wäre schön, wenn dies auch auf Ziffern aufgeteilt würde. Ich möchte auch, dass es in aufeinanderfolgende Großbuchstaben aufgeteilt wird. Ich habe diese Pipe, die großartig funktioniert, außer dass sie nur in Chrome und nicht in Firefox funktioniert. Offensichtlich unterstützt nur Chrome Lookbacks. Wie kann dies ohne Rückblicke erreicht werden?

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

So sollte beispielsweise eine Zeichenfolge ANet15Amountin transformiert werden A Net 15 Amount. Dieser reguläre Ausdruck würde auch eine camelCase-Zeichenfolge aufteilen, dies muss jedoch nicht berücksichtigt werden.

develmatik
quelle
.replace(/([A-Z]|\d+)/g, " $1").trim();
Ibrahim Mahrir
2
@ibrahimmahrir (?!^)([A-Z]|\d+)vermeidet das erste Leerzeichen und benötigt keine Trimmung.
Ctwheels

Antworten:

6

Wie wäre es passend durch ein Grundmuster wie diese und Verbinden mit dem Raum.

let str = `ANet15Amount`;

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

console.log(camel);

Zuerst habe ich einfach darüber nachgedacht, [A-Z][a-z]*|\d+aber dies würde z. B. ABCDefg123in A B C Defg 123eine andere Funktion als Ihre aktuelle Funktion einbrechen , die sich in verwandelt ABC Defg 123.

Es gibt noch einen kleinen Unterschied. Deiner verwandelt sich A1B2in A 1B 2und dieser dorthin, A 1 B 2wo ich denke, dass dieser genauer wäre, nicht wahr?

Wackelblase
quelle
1
Genial, habe alle meine Testfälle bestanden. Ich stimme zu, Ihre ist genauer. Ich weiß das wirklich zu schätzen!
Develmatik
@develmatik Ich bin froh, dass es wie gewünscht funktioniert, ich habe gerade über die Unterschiede von Camel zu PascalCase gelesen :)
Bobble Bubble
3

Ersetzen Sie einfach einen Großbuchstaben [A-Z]oder eine Ziffernfolge \d+durch ein Leerzeichen plus das, was wir gerade gefunden haben " $1". Wir überspringen den ersten Buchstaben, damit zu Beginn der resultierenden Zeichenfolge kein Leerzeichen hinzugefügt wird, indem am Anfang der Zeichenfolge ein negativer Lookahead hinzugefügt wird (?!^):

// ...

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

Beispiel:

ibrahim mahrir
quelle
2

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

  • 0 oder 1 Großbuchstabe direkt gefolgt von 1 oder mehr Kleinbuchstaben
  • oder 1 Großbuchstabe
  • oder 1 oder mehr Ziffern

Test im Generator: https://regex101.com/r/uBO0P5/1

Tony
quelle
2

Ich denke, es hängt von den Konventionen der Zeichenfolge ab, die die Komplexität erhöhen können

// 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
quelle