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


8

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

AddData
TestSomething
TellMeWhoYouAre

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


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

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


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"

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


Краткость приемлема, но полные объяснения лучше. , Кроме того, в чем смысл [^^]("не карет ( ^)")?
Кусалананда

@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:]:чтобы избежать печати этого ненужного места в начале каждой строки вывода.
Пол Эванс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.