Добавить пробел перед заглавной буквой

8

У меня есть строки:

AddData
TestSomething
TellMeWhoYouAre

и так далее. Я хочу добавить пробел перед заглавными буквами. Как мне это сделать?

HeroFromEarth
источник
7
Что вы хотите сделать, когда есть последовательные заглавные буквы? примерIClimbALadder
Гленн Джекман
1
На самом деле у меня есть строки вроде, ReadFileFromCDDriveи решение @Kusalananda прекрасно работает.
HeroFromEarth

Ответы:

16

Используя sedи предполагая, что вы не хотите пробела перед словом:

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

Подстановка будет искать заглавную букву сразу после другого непробельного символа и вставлять пробел между ними.

Для строк с более чем одним последовательным символом верхнего регистра, как WeAreATeam, например , это производит We Are ATeam. Чтобы отсортировать это, запустите замену второй раз:

$ sed -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' \
      -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Кусалананда
источник
1
Этот ответ не будет добавлять пробел перед заглавной буквой, если ему предшествует заглавная буква. Зачем писать так, когда ОП не накладывает на него таких ограничений?
LarsH
@LarsH Исправлено.
Кусалананда
Нет, ты не сделал. Вы не можете иметь совпадения с регулярным выражением, даже с gфлагом. Попробуйте echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g'(ваша команда), чтобы увидеть, почему это не работает.
Wildcard
@ Wildcard Wonky, но работает. У вас есть лучшее предложение, используя BRE?
Кусалананда
На самом деле он не говорит, что в начале нет пробела, поэтому s/[A-Z]/ \0/gвполне удовлетворителен ... `s / [AZ] / \ 0 / g; s / ^ // ', если вам действительно все равно.
Майкл Гомер
12

Perl, используя регулярные выражения lookbehind и lookahead с нулевой шириной:

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

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

Эта версия также разделяет последовательные заглавные буквы.

JJoao
источник
1
Это превращается ReadFileFromUSBDriveв Read File From U S B Driveто время как ОП хотел Read File From USB Drive.
Кусалананда
1
@Kusalananda, спасибо, что указали на это. (Боюсь, я не вижу того, что написано в вопросе). В реальных ситуациях (понимание программирования, расширение слов идентификатора и варианты CamelCase) обычно используют базовые критерии (разделенные на один верхний регистр или наоборот) и есть словарь исключений.
JJoao
1
Извините, это было то, что ОП написал в комментариях к моему ответу. Я согласен, это трудно сделать без какого-либо списка слов.
Кусалананда
2
sed -r -e "s/([^A-Z])([A-Z])/\1 \2/g"

Добавьте пробел между буквой, которая не является заглавной буквой, и буквой, которая является заглавной буквой

ka3ak
источник
Краткость приемлема, но полные объяснения лучше. , Кроме того, в чем смысл [^^]("не карет ( ^)")?
Кусалананда
@Kusalananda Вы правы. Пробел не будет вставлен между ^ и Add в «^ AddData». Я отредактировал свой ответ.
ka3ak
0

Решение 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="")

Тестовый забег:

$ ./add_space_to_upper.py input.txt                        
 Add Data
 Test Something
 Tell Me Who You Are
Сергей Колодяжный
источник
Вы хотите print(line[0], end="")следовать, for char in line[1:]:чтобы избежать печати этого ненужного места в начале каждой строки вывода.
Пол Эванс