Fügen Sie vor dem Großbuchstaben Leerzeichen ein


8

Ich habe eine Saite:

AddData
TestSomething
TellMeWhoYouAre

und so weiter. Ich möchte vor Großbuchstaben Leerzeichen einfügen. Wie kann ich es tun?


7
Was möchten Sie tun, wenn aufeinanderfolgende Großbuchstaben vorhanden sind? BeispielIClimbALadder
Glenn Jackman

1
Eigentlich habe ich eine Zeichenfolge wie ReadFileFromCDDriveund @Kusalanandas Lösung funktioniert großartig.
HeroFromEarth

Antworten:


16

Verwenden sedund vorausgesetzt, Sie möchten kein Leerzeichen vor dem Wort:

$ sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Add Data
Test Something
Tell Me Who You Are

Bei der Ersetzung wird nach einem Großbuchstaben gesucht, der unmittelbar auf ein anderes Nicht-Leerzeichen folgt, und ein Leerzeichen zwischen den beiden eingefügt.

WeAreATeamDies ergibt für Zeichenfolgen mit mehr als einem aufeinanderfolgenden Großbuchstaben Folgendes We Are ATeam. Führen Sie die Substitution ein zweites Mal aus, um dies zu sortieren:

$ sed -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' \
      -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in

1
Diese Antwort fügt vor einem Großbuchstaben kein Leerzeichen ein, wenn vor einem Großbuchstaben steht. Warum so schreiben, wenn das OP keine solche Einschränkung auferlegt hat?
LarsH

@LarsH Es wurde behoben.
Kusalananda

Nein, hast du nicht. Sie können keine überlappenden Übereinstimmungen mit einem regulären Ausdruck haben, auch nicht mit einer gFlagge. Versuchen Sie echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g'(Ihr Befehl) herauszufinden, warum es nicht funktioniert.
Wildcard

@ Wildcard Wonky, funktioniert aber. Haben Sie einen besseren Vorschlag für die Verwendung von BREs?
Kusalananda

Es ist nicht wirklich sagen , keinen Platz zu Beginn, so s/[A-Z]/ \0/gganz zufrieden stellend ist ... `s / [AZ] / \ 0 / g; s / ^ //‘ , wenn Sie wirklich interessieren.
Michael Homer

12

Perl, mit regulären Ausdrücken von lookbehind und lookahead mit der Breite Null:

$ perl -pe 's/(?<=\w)(?=[A-Z])/ /g'  file.in 

Tell Me Who You Are                    ## TellMeWhoYouAre
I Am A Regular Expression User         ## IAmARegulaExpressionUser

Diese Version trennt auch aufeinanderfolgende Großbuchstaben.


1
Dies wird ReadFileFromUSBDrivezu, Read File From U S B Drivewährend das OP wollte Read File From USB Drive.
Kusalananda

1
@Kusalananda, danke, dass du darauf hingewiesen hast. (Ich fürchte, ich sehe das nicht in der Frage). In realen Situationen (Programmierverständnis, Erweiterung von ID-Wörtern und CamelCase-Varianten) wird häufig ein grundlegendes Kriterium verwendet (entweder in Großbuchstaben oder umgekehrt) und es gibt ein Wörterbuch mit Ausnahmen.
JJoao

1
Entschuldigung, das hat das OP in den Kommentaren zu meiner Antwort geschrieben. Ich stimme zu, es ist schwierig, dies ohne eine Wortliste zu tun.
Kusalananda


0

Python-Lösung:

#!/usr/bin/env python
from __future__ import print_function
import sys

with open(sys.argv[1]) as f:
    for line in f:
        for char in line:
            if char.isupper():
               print(" "+char,end="")
            else:
               print(char,end="")

Testlauf:

$ ./add_space_to_upper.py input.txt                        
 Add Data
 Test Something
 Tell Me Who You Are

Sie wollen print(line[0], end="")gefolgt von for char in line[1:]:Drucken , dass unerwünschte Leerzeichen am Anfang jeder Ausgangsleitung zu vermeiden.
Paul Evans
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.