簡體   English   中英

REGEX:用一兩個字母刪除字符串之間的空格

[英]REGEX: Remove spaces between strings with one or two letters

考慮下表第一列中顯示的以下原始字符串:

Original String                  Parsed String                   Desired String
'W. & J. JOHNSON LMT.COM'       #W    J  JOHNSON LIMITED        #WJ JOHNSON LIMITED
'NORTH ROOF & WORKS CO. LTD.'   #NORTH ROOF   WORKS CO  LTD     #NORTH ROOF WORKS CO LTD
'DAVID DOE & CO., LIMITED'      #DAVID DOE   CO   LIMITED       #DAVID DOE CO LIMITED
'GEORGE TV & APPLIANCE LTD.'    #GEORGE TV   APPLIANCE LTD      #GEORGE TV APPLIANCE LTD 
'LOVE BROS. & OTHERS LTD.'      #LOVE BROS    OTHERS LTD        #LOVE BROS OTHERS LTD
'A. B. & MICHAEL CLEAN CO. LTD.'#A  B    MICHAEL CLEAN CO  LTD  #AB MICHAEL CLEAN CO LTD
'C.M. & B.B. CLEANER INC.'      #C M    B B  CLEANER INC        #CMBB CLEANER INC

需要刪除標點符號,我已完成如下操作:

def transform(word):
    word = re.sub(r'(?<=[A-Za-z])\'(?=[A-Za-z])[A-Z]|[^\w\s]|(.com|COM)',' ',word)

但是,還有最后一點我沒有得到。 刪除標點符號后,我得到了很多空格。 我怎樣才能有一個正則表達式將首字母放在一起並為常規單詞保留單個空格(無首字母)?

這是替換提到的字符以獲得所需字符串的糟糕方法嗎?

謝謝你讓我繼續學習:)

我認為分部分執行此操作更簡單。 首先,刪除.com和除space&之外的任何標點符號。 然后,刪除僅由一個字母包圍的space& 最后,用一個space替換任何剩余的space&序列:

import re
strings = ['W. & J. JOHNSON LMT.COM',
'NORTH ROOF & WORKS CO. LTD.',
'DAVID DOE & CO., LIMITED',
'GEORGE TV & APPLIANCE LTD.',
'LOVE BROS. & OTHERS LTD.',
'A. B. & MICHAEL CLEAN CO. LTD.',
'C.M. & B.B. CLEANER INC.'
]

for s in strings:
    s = re.sub(r'\.COM|[^a-zA-Z& ]+', '', s, 0, re.IGNORECASE)
    s = re.sub(r'(?<=\b\w)\s*[ &]\s*(?=\w\b)', '', s)
    s = re.sub(r'\s*[& ]\s*', ' ', s)
    print s

輸出

WJ JOHNSON LMT
NORTH ROOF WORKS CO LTD
DAVID DOE CO LIMITED
GEORGE TV APPLIANCE LTD
LOVE BROS OTHERS LTD
AB MICHAEL CLEAN CO LTD
CM BB CLEANER INC

雷克斯特演示

更新

這是在編輯更改最后數據所需結果的問題之前編寫的。 鑒於編輯,上面的代碼可以簡化為

for s in strings:
     s = re.sub(r'\.COM|[^a-zA-Z ]+|\s(?=&)|(?<!\w\w)\s+(?!\w\w)', '', s, 0, re.IGNORECASE)
     print s

雷克斯特演示

單獨在正則表達式中執行此操作不會很漂亮,也不是最好的解決方案,但是,它來了! 您最好采用多步方法。 我所做的是確定所有可能的情況並選擇找到沒有替換字符串的解決方案,因為您並不總是用空格替換字符。


規則

  1. 非“堆疊”縮寫
    • 這些是ABW. & J.類的位置,但不是CM & BB
    • 我已經將這些確定為縮寫部分(例如A. )前后存在的位置,但后者后面沒有另一個字母字符
  2. 前面的空格
    • 這些位置在您的文本中不存在,但如果在非字母字符之前有一個空格而其后沒有空格(例如在行尾)
    • 在這些情況下,我們匹配第一個空格之后的字符
  3. 行進空間
    • 這些是像&J.的點這樣的位置J.
    • 我們匹配那些例子中最后一個空格之前的字符
  4. 沒空間了
    • 這些位置類似於'LOVE (該字符串中的撇號)
    • 我們只匹配非字母非空白字符

正則表達式

完成此操作的多合一正則表達式如下:

請參閱此處使用的正則表達式

(?<=\b[a-z])[^a-z]+(?=[a-z]\b(?![^a-z][a-z]))|(?<= ) *(?:\.com\b|[^a-z\s]+) *| *(?:\.com\b|[^a-z\s]+) *(?= )|(?<! )(?:\.com\b|[^a-z\s]+)(?! )

工作原理如下(分為每個交替):

  • (?<=\\b[az])[^az]+(?=[az]\\b(?![^az][az]))匹配A.B.之間的非字母字符,但不匹配A.BB
    • (?<=\\b[az])正向后視確保前面是字母字符並在其左側斷言單詞邊界位置
    • [^az]+匹配任何非字母字符一次或多次
    • (?=[az]\\b(?![^az][az]))正向前瞻確保以下存在
      • [az]\\b匹配任何字母字符並在其右側斷言單詞邊界位置
      • (?![^az][az])負前瞻確保后面的不是非字母字符后跟字母字符
  • (?<= ) *(?:\\.com\\b|[^az\\s]+) *確保前面有一個空格,然后匹配任何空格、 .com或任何非單詞非空白字符一次或多次,然后是任何空格
    • (?<= )正向后視確保前面有一個空格
    • *匹配任意數量的空格
    • (?:\\.com\\b|[^az\\s]+)匹配.com並確保跟隨一個非單詞字符,或匹配任何非單詞非空白字符一次或多次
    • *匹配任意數量的空格
  • *(?:\\.com\\b|[^az\\s]+) *(?= )匹配任何空格、 .com或任何非單詞非空白字符一次或多次,然后匹配任何空格,然后確保一個空格跟隨
    • 與之前的相同,但不是開始時的正面回顧,而是結尾的正面回顧
  • (?<! )(?:\\.com\\b|[^az\\s]+)(?! )匹配.com或任何非字母非空白字符一次或多次確保沒有空格包圍它
    • 與前兩個選項相同,但使用負后視和負前瞻

代碼

在此處查看正在使用的代碼

import re

strings = [
    "'W. & J. JOHNSON LMT.COM'",
    "'NORTH ROOF & WORKS CO. LTD.'",
    "'DAVID DOE & CO., LIMITED'",
    "'GEORGE TV & APPLIANCE LTD.'",
    "'LOVE BROS. & OTHERS LTD.'",
    "'A. B. & MICHAEL CLEAN CO. LTD.'",
    "'C.M. & B.B. CLEANER INC.'"
]

r = re.compile(r'(?<=\b[a-z])[^a-z]+(?=[a-z]\b(?![^a-z][a-z]))|(?<= ) *(?:\.com\b|[^a-z\s]+) *| *(?:\.com\b|[^a-z\s]+) *(?= )|(?<! )(?:\.com\b|[^a-z\s]+)(?! )', re.IGNORECASE)

def transform(word):
    return re.sub(r, '', word)

for s in strings:
    print(transform(s))

輸出:

WJ JOHNSON LMT
NORTH ROOF WORKS CO LTD
DAVID DOE CO LIMITED
GEORGE TV APPLIANCE LTD
LOVE BROS OTHERS LTD
AB MICHAEL CLEAN CO LTD
CM BB CLEANER INC

編輯

使用回調,您可以擴展此邏輯以包含在我的答案下方的評論中提到的特殊情況,以匹配特定情況並進行條件替換。

這些特殊情況包括:

  • FONTAINE'S到方FONTAINE
  • PREMIUM-FIT AUTOPREMIUM FIT AUTO
  • 62325 WC62325 WC

我在正則表達式中添加了一個新的交替: (\\b[\\'-]\\b(?:[az\\d] )?)以捕獲字母之間的'S- (也-S或類似的)並將其替換為空間使用回調(如果捕獲組存在)。

我仍然建議使用多個正則表達式來實現這一點,但我想證明使用單個模式是可能的。

在此處查看正在使用的代碼

import re

strings = [
    "'W. & J. JOHNSON LMT.COM'",
    "'NORTH ROOF & WORKS CO. LTD.'",
    "'DAVID DOE & CO., LIMITED'",
    "'GEORGE TV & APPLIANCE LTD.'",
    "'LOVE BROS. & OTHERS LTD.'",
    "'A. B. & MICHAEL CLEAN CO. LTD.'",
    "'C.M. & B.B. CLEANER INC.'",
    "'FONTAINE'S PREMIUM-FIT AUTO 62325 W.C.'"
]

r = re.compile(r'(?<=\b[a-z\d])[^a-z\d]+(?=[a-z\d]\b(?![^a-z\d][a-z\d]))|(?<= ) *(?:\.com\b|[^a-z\d\s]+) *| *(?:\.com\b|[^a-z\d\s]+) *(?= )|(\b[\'-]\b(?:[a-z\d] )?)|(?<! )(?:\.com\b|[^a-z\d\s]+)(?! )', re.IGNORECASE)

def repl(m):
    return ' ' if m.group(1) else ''

for s in strings:
    print(r.sub(repl, s))

這是我可以用一種正則表達式模式得到的最簡單的方法:

\\.COM|(?<![AZ]{2}) (?![AZ]{2})|[.&,]| (?>)&

基本上,它會刪除符合 3 個條件的字符:

  1. 文字“.COM”
  2. 前面或后面沒有 2 個大寫字母的空格
  3. 點、與號和逗號,無論它們出現在哪里
  4. 后跟與符號的空格

演示: https : //regex101.com/r/EMHxq9/2

暫無
暫無

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

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