簡體   English   中英

在大寫字母前插入空格的pythonic方法

[英]A pythonic way to insert a space before capital letters

我有一個文件,我正在通過 python 腳本更改其格式。 我在這個文件中有幾個駝峰式字符串,我只想在大寫字母前插入一個空格 - 所以“WordWordWord”變成了“Word Word Word”。

我有限的正則表達式經驗剛剛在我身上停滯不前 - 有人可以想到一個像樣的正則表達式來做到這一點,或者(更好)有沒有更pythonic的方法來做到這一點,我錯過了?

你可以試試:

>>> re.sub(r"(\w)([A-Z])", r"\1 \2", "WordWordWord")
'Word Word Word'

如果有連續的大寫字母,則 Gregs 結果可能不是您要查找的內容,因為 \\w 消耗了要替換的大寫字母前面的字符。

>>> re.sub(r"(\w)([A-Z])", r"\1 \2", "WordWordWWWWWWWord")
'Word Word WW WW WW Word'

后視可以解決這個問題:

>>> re.sub(r"(?<=\w)([A-Z])", r" \1", "WordWordWWWWWWWord")
'Word Word W W W W W W Word'

看看我在.NET 上的回答- 如何將“大寫”分隔的字符串拆分為數組?

編輯:也許更好地將它包含在這里。

re.sub(r'([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))', r'\1 ', text)

例如:

"SimpleHTTPServer" => ["Simple", "HTTP", "Server"]

也許更短:

>>> re.sub(r"\B([A-Z])", r" \1", "DoIThinkThisIsABetterAnswer?")

也許您會對不使用正則表達式的單行實現感興趣:

''.join(' ' + char if char.isupper() else char.strip() for char in text).strip()

使用正則表達式,您可以執行以下操作:

re.sub('([A-Z])', r' \1', str)

當然,這僅適用於 ASCII 字符,如果您想使用 Unicode,它是一種全新的蠕蟲:-)

如果您有首字母縮略詞,您可能不希望它們之間有空格。 這個兩階段正則表達式將保持首字母縮寫詞完整(並且還將標點符號和其他非大寫字母視為添加空格的東西):

re_outer = re.compile(r'([^A-Z ])([A-Z])')
re_inner = re.compile(r'(?<!^)([A-Z])([^A-Z])')
re_outer.sub(r'\1 \2', re_inner.sub(r' \1\2', 'DaveIsAFKRightNow!Cool'))

輸出將是: 'Dave Is AFK Right Now! Cool' 'Dave Is AFK Right Now! Cool'

我同意正則表達式解決方案是最簡單的,但我不會說它是最 Pythonic 的。

怎么樣:

text = 'WordWordWord'
new_text = ''

for i, letter in enumerate(text):
    if i and letter.isupper():
        new_text += ' '

    new_text += letter

我認為正則表達式是通往這里的方式,但只是為了提供一個純 python 版本,而沒有(希望)任何 ΤΖΩΤΖΙΟΥ 指出的問題:

def splitCaps(s):
    result = []
    for ch, next in window(s+" ", 2):
        result.append(ch)
        if next.isupper() and not ch.isspace():
            result.append(' ')
    return ''.join(result)

window() 是我用來操作項目的滑動窗口的實用函數,定義為:

import collections, itertools

def window(it, winsize, step=1):
    it=iter(it)  # Ensure we have an iterator
    l=collections.deque(itertools.islice(it, winsize))
    while 1:  # Continue till StopIteration gets raised.
        yield tuple(l)
        for i in range(step):
            l.append(it.next())
            l.popleft()

對於舊線程 - 想嘗試滿足我的一個要求的選項。 當然, re.sub()是很酷的解決方案,但如果不(或不應該)導入 re 模塊,也會得到一個 1 liner。

st = 'ThisIsTextStringToSplitWithSpace'
print(''.join([' '+ s if s.isupper()  else s for s in st]).lstrip())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM