Tambahkan spasi sebelum huruf besar

8

Saya punya string:

AddData
TestSomething
TellMeWhoYouAre

dan seterusnya. Saya ingin menambahkan spasi sebelum huruf besar. Bagaimana saya bisa melakukannya?

HeroFromEarth
sumber
7
Apa yang ingin Anda lakukan ketika ada huruf besar berturut-turut? contohIClimbALadder
glenn jackman
1
Sebenarnya saya punya string seperti ReadFileFromCDDrivedan solusi @Kusalananda berfungsi dengan baik.
HeroFromEarth

Jawaban:

16

Menggunakan sed, dan dengan asumsi Anda tidak ingin spasi di depan kata:

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

Substitusi akan mencari huruf besar segera setelah karakter non-spasi putih lainnya, dan menyisipkan spasi di antara keduanya.

Untuk string dengan lebih dari satu karakter huruf besar berturut-turut, seperti WeAreATeam, ini menghasilkan We Are ATeam. Untuk mengurutkan ini, jalankan subtitusi kedua kalinya:

$ sed -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' \
      -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Kusalananda
sumber
1
Jawaban ini tidak akan menambah spasi sebelum huruf besar jika didahului dengan huruf besar. Mengapa menulis seperti itu, ketika OP tidak membatasi seperti itu?
LarsH
@ LarsH Memperbaikinya.
Kusalananda
Tidak, kamu tidak. Anda tidak dapat memiliki pertandingan yang tumpang tindih dengan regex, bahkan dengan gbendera. Coba echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g'(perintah Anda) untuk melihat mengapa itu tidak berhasil.
Wildcard
@ Kartu Memori Wonky, tapi berhasil. Apakah Anda memiliki saran yang lebih baik menggunakan BRE?
Kusalananda
Itu sebenarnya tidak mengatakan tidak ada ruang di awal, jadi s/[A-Z]/ \0/gsepenuhnya memuaskan ... `s / [AZ] / \ 0 / g; s / ^ // 'jika Anda benar-benar peduli.
Michael Homer
12

Perl, menggunakan lookbehind dan lookahead ekspresi reguler nol-lebar:

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

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

Versi ini juga memisahkan huruf besar berturut-turut.

Joao
sumber
1
Ini berubah ReadFileFromUSBDrivemenjadi Read File From U S B Driveyang diinginkan OP Read File From USB Drive.
Kusalananda
1
@ Kusalananda, terima kasih telah menunjukkannya. (Saya khawatir saya tidak melihat itu tertulis dalam pertanyaan). Dalam situasi nyata (pemahaman pemrograman, perluasan kata-kata id, dan varian CamelCase) adalah umum untuk menggunakan kriteria dasar (baik dibagi menjadi huruf besar tunggal atau sebaliknya) dan memiliki kamus pengecualian.
JJoao
1
Maaf, itu adalah sesuatu yang OP tulis dalam komentar untuk jawaban saya. Saya setuju, sulit melakukan ini tanpa daftar kata.
Kusalananda
2
sed -r -e "s/([^A-Z])([A-Z])/\1 \2/g"

Tambahkan spasi antara huruf yang bukan huruf besar dan huruf yang merupakan huruf besar

ka3ak
sumber
Brevity dapat diterima, tetapi penjelasan yang lebih lengkap lebih baik. . Selain itu, apa gunanya [^^]("bukan tanda sisipan ( ^)")?
Kusalananda
@ Kusalananda Anda benar. Spasi tidak akan disisipkan di antara ^ dan Tambah di "^ AddData". Saya sudah mengedit jawaban saya.
ka3ak
0

Solusi 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="")

Uji coba:

$ ./add_space_to_upper.py input.txt                        
 Add Data
 Test Something
 Tell Me Who You Are
Sergiy Kolodyazhnyy
sumber
Anda ingin print(line[0], end="")diikuti oleh for char in line[1:]:untuk menghindari mencetak ruang yang tidak diinginkan di awal setiap baris output.
Paul Evans