Agregar espacio antes de la letra mayúscula

8

Tengo unas cuerdas:

AddData
TestSomething
TellMeWhoYouAre

y así. Quiero agregar espacio antes de las letras mayúsculas. ¿Cómo puedo hacerlo?

HéroeDe Tierra
fuente
77
¿Qué quieres hacer cuando hay letras mayúsculas consecutivas? ejemploIClimbALadder
Glenn Jackman
1
En realidad, tengo ReadFileFromCDDrivealgunas cadenas como y la solución de @Kusalananda funciona muy bien.
HeroFromEarth

Respuestas:

16

Usando sed, y asumiendo que no quieres un espacio delante de la palabra:

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

La sustitución buscará una letra mayúscula inmediatamente después de otro carácter que no sea un espacio en blanco e insertará un espacio entre los dos.

Para cadenas con más de un carácter de mayúsculas consecutivas, como WeAreATeam, esto produce We Are ATeam. Para ordenar esto, ejecute la sustitución por segunda vez:

$ sed -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' \
      -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Kusalananda
fuente
1
Esta respuesta no agregará un espacio antes de una letra mayúscula si está precedida por una letra mayúscula. ¿Por qué escribirlo de esa manera, cuando el OP no le impuso ninguna restricción?
LarsH
@LarsH lo arregló.
Kusalananda
No, no lo hiciste. No puede tener coincidencias superpuestas con una expresión regular, incluso con una gbandera. Pruebe echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g'(su comando) para ver por qué no funciona.
Comodín
@Wildcard Wonky, pero funciona. ¿Tiene una mejor sugerencia para usar BRE?
Kusalananda
En realidad no dice ningún espacio al principio, por lo que s/[A-Z]/ \0/ges completamente satisfactorio ... `s / [AZ] / \ 0 / g; s / ^ // 'si realmente te importa.
Michael Homer
12

Perl, usando expresiones regulares de ancho cero y mirar hacia atrás:

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

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

Esta versión también está separando letras mayúsculas consecutivas.

JJoao
fuente
1
Esto se convierte ReadFileFromUSBDriveen Read File From U S B Drivemientras que el OP quería Read File From USB Drive.
Kusalananda
1
@Kusalananda, gracias por señalarlo. (Me temo que no veo eso escrito en la pregunta). En situaciones reales (comprensión de programación, expansión de palabras de identificación y variantes de CamelCase) es común usar un criterio básico (dividido en mayúsculas o en opuesto) y tener un diccionario de excepciones.
JJoao
1
Lo siento, fue algo que el OP escribió en los comentarios a mi respuesta. Estoy de acuerdo, es difícil hacer esto sin una lista de palabras de algún tipo.
Kusalananda
0

Solución 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="")

Prueba de funcionamiento:

$ ./add_space_to_upper.py input.txt                        
 Add Data
 Test Something
 Tell Me Who You Are
Sergiy Kolodyazhnyy
fuente
Desea print(line[0], end="")seguir for char in line[1:]:para evitar imprimir ese espacio no deseado al comienzo de cada línea de salida.
Paul Evans