Adicionar espaço antes da letra maiúscula


8

Eu tenho uma corda:

AddData
TestSomething
TellMeWhoYouAre

e assim por diante. Quero adicionar espaço antes de letras maiúsculas. Como eu posso fazer isso?


7
O que você deseja fazer quando houver letras maiúsculas consecutivas? exemploIClimbALadder
glenn jackman

1
Na verdade, eu tenho algumas strings ReadFileFromCDDrivee a solução do @Kusalananda funciona muito bem.
HeroFromEarth 02/02

Respostas:


16

Usando sede assumindo que você não deseja um espaço na frente da palavra:

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

A substituição procurará uma letra maiúscula imediatamente após outro caractere que não seja um espaço em branco e inserirá um espaço entre os dois.

Para seqüências com mais de um caractere maiúsculo consecutivo, como WeAreATeam, isso produz We Are ATeam. Para classificar isso, execute a substituição uma segunda vez:

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

1
Esta resposta não adicionará um espaço antes de uma letra maiúscula se for precedida por uma letra maiúscula. Por que escrever dessa maneira, quando o OP não impôs nenhuma restrição a ele?
LarsH

@LarsH Corrigido.
Kusalananda

Não, você não fez. Você não pode ter correspondências sobrepostas em uma regex, mesmo com um gsinalizador. Tente echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g'(seu comando) para ver por que não funciona.
Curinga

@Wildcard Wonky, mas funciona. Você tem uma sugestão melhor usando BREs?
Kusalananda

Na verdade, ele não diz que não há espaço no início, então s/[A-Z]/ \0/gé totalmente satisfatório ... `s / [AZ] / \ 0 / g; s / ^ // 'se você realmente se importa.
Michael Homer

12

Perl, usando expressões regulares lookbehind e lookahead com largura zero:

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

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

Esta versão também está separando letras maiúsculas consecutivas.


1
Isso se transforma ReadFileFromUSBDriveno Read File From U S B Driveque o OP queria Read File From USB Drive.
Kusalananda

1
@ Kusalananda, obrigado por apontar. (Receio não ver isso escrito na pergunta). Em situações reais (entendimento de programação, expansão de palavras-chave e variantes do CamelCase), é comum usar um critério básico (dividido em maiúsculas ou o oposto) e ter um dicionário de exceções.
JJoao

1
Desculpe, foi algo que o OP escreveu nos comentários da minha resposta. Concordo, é difícil fazer isso sem uma lista de palavras de algum tipo.
Kusalananda


0

Solução 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="")

Execução de teste:

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

Você deseja print(line[0], end="")seguir for char in line[1:]:para evitar a impressão desse espaço indesejado no início de cada linha de saída.
Paul Evans
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.