Ajouter un espace avant la lettre majuscule

8

J'ai des cordes:

AddData
TestSomething
TellMeWhoYouAre

etc. Je veux ajouter de l'espace avant les lettres majuscules. Comment puis-je le faire?

HeroFromEarth
la source
7
Que voulez-vous faire lorsqu'il y a des majuscules consécutives? exempleIClimbALadder
glenn jackman
1
En fait, j'ai des chaînes comme ReadFileFromCDDriveet la solution de @Kusalananda fonctionne très bien.
HeroFromEarth

Réponses:

16

En utilisant sedet en supposant que vous ne voulez pas d'espace devant le mot:

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

La substitution recherchera une lettre majuscule immédiatement après un autre caractère non blanc et insérera un espace entre les deux.

Pour les chaînes avec plus d'un caractère majuscule consécutif, par exemple WeAreATeam, cela produit We Are ATeam. Pour trier cela, exécutez la substitution une deuxième fois:

$ sed -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' \
      -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Kusalananda
la source
1
Cette réponse n'ajoutera pas d'espace avant une lettre majuscule si elle est précédée d'une lettre majuscule. Pourquoi l'écrire de cette façon, alors que le PO ne lui a imposé aucune restriction?
LarsH
@LarsH Le fixe.
Kusalananda
Non tu ne l'as pas fait. Vous ne pouvez pas avoir de correspondances qui se chevauchent avec une expression régulière, même avec un gindicateur. Essayez echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g'(votre commande) pour voir pourquoi cela ne fonctionne pas.
Wildcard
@Wildcard Wonky, mais fonctionne. Avez-vous une meilleure suggestion en utilisant des BRE?
Kusalananda
Il ne dit en fait pas d'espace au début, c'est donc s/[A-Z]/ \0/gtout à fait satisfaisant ... `s / [AZ] / \ 0 / g; s / ^ // 'si vous vous en souciez vraiment.
Michael Homer
12

Perl, en utilisant les expressions régulières de largeur nulle lookbehind et lookahead:

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

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

Cette version sépare également les lettres majuscules consécutives.

JJoao
la source
1
Cela se transforme ReadFileFromUSBDriveen Read File From U S B Drivealors que l'OP voulait Read File From USB Drive.
Kusalananda
1
@Kusalananda, merci de l'avoir signalé. (J'ai bien peur de ne pas voir cela écrit dans la question). Dans des situations réelles (compréhension de la programmation, extension des mots id et variantes CamelCase), il est courant d'utiliser des critères de base (soit divisés en majuscules simples ou l'inverse) et d'avoir un dictionnaire d'exceptions.
JJoao
1
Désolé, c'est quelque chose que le PO a écrit dans les commentaires de ma réponse. Je suis d'accord, il est difficile de le faire sans une liste de mots.
Kusalananda
0

Solution Python:

#!/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="")

Essai:

$ ./add_space_to_upper.py input.txt                        
 Add Data
 Test Something
 Tell Me Who You Are
Sergiy Kolodyazhnyy
la source
Vous voulez print(line[0], end="")suivre for char in line[1:]:pour éviter d'imprimer cet espace indésirable au début de chaque ligne de sortie.
Paul Evans