Фильтрация текста, который заканчивается определенным символом (все вхождения) в python через регулярное выражение

#python #regex #text #filtering

#python #регулярное выражение #текст #фильтрация

Вопрос:

Я пытаюсь отфильтровать текст в python

 import re
text = "Fast charging 25W, USB Power Delivery 3.0, Fast Qi/PMA wireless charging 12W, Reverse wireless charging 4.5W"
regex = re.compile("w sw hargw sd W")  
mc = regex.findall(text)
print(mc)
 

Результат

[‘Быстрая зарядка 25 Вт’, ‘беспроводная зарядка 12 Вт’]

Однако я хочу, чтобы все вхождения заканчивались на * W »

[‘Быстрая зарядка 125 Вт’, ‘Быстрая беспроводная зарядка Qi / PMA 12 Вт’, ‘Обратная беспроводная зарядка 4,5 Вт’]

Число может быть намного больше (например, Charge 1250W) Я гуглил почти 2 часа с большим количеством документов о регулярных выражениях, но тщетно. любая помощь будет оценена.

Спасибо.

Комментарии:

1. Вы все равно можете проголосовать за ответы, независимо от принятия, чтобы отметить усилия. 🙂

2. это полезно знать, спасибо!

3. @Josh Kim: Привет, Джош, ты все еще можешь проголосовать за ответы ;-), см. Мои ниже!

Ответ №1:

Вы ищете границу слова и, если я правильно понимаю, все между запятыми:

 [^,] ?Wb
 
  • Все, что не является запятой, лениво
  • Буквенный верхний регистр W , за которым следует граница слова b

Онлайн-демонстрация, пример кода:

 import re
regex = r"[^,] ?Wb"
test_str = ("text = "Fast charging 25W, USB Power Delivery 3.0, Fast Qi/PMA wireless charging 12W, Reverse wireless charging 4.5W"n")
matches = re.finditer(regex, test_str, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):  
    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
 

Комментарии:

1. Вот пример кода, используемый finditer для получения отдельных результатов: ideone.com/VZVwzT

2. Я думаю, вам не нужно делать его не жадным, так как W стоит перед запятой, как [^,] Wb 1

Ответ №2:

Вы можете начать сопоставление с символом слова, сопоставить начисление между символами, которые не являются запятой, а затем сопоставить хотя бы цифру перед W

 (?<!S)[^,]*bchargw b[^,]*dWb
 

Объяснение

  • (?<!S) Установите границу пробела слева
  • [^,]* Сопоставьте 0 вхождений любого символа, кроме ,
  • bchargw b Граница слова, совпадение charg , за которым следуют символы 1 слов и граница слова
  • [^,]* Сопоставьте 0 вхождений любого символа, кроме ,
  • dWb Сопоставьте хотя бы одну цифру, за которой следует, W и границу слова

Демонстрация регулярных выражений

 import re

s = "Fast charging 25W, USB Power Delivery 3.0, Fast Qi/PMA wireless charging 12W, Reverse wireless charging 4.5W, Charge 1250W"
print(re.findall(r"(?<!S)[^,]*bchargw b[^,]*dWb", s, re.IGNORECASE))
 

Вывод

 [
    'Fast charging 25W',
    'Fast Qi/PMA wireless charging 12W',
    'Reverse wireless charging 4.5W',
    'Charge 1250W'
]
 

Или, если в части с могут быть только цифры W , вы также можете исключить совпадение цифр [^,d] и, при необходимости, сопоставить десятичную часть (?:.d )?

 (?<!S)[^,]*bchargw b[^,d]*d (?:.d )?Wb
 

Демонстрация регулярных выражений

Комментарии:

1. Спасибо за ваше любезное объяснение. Как жаль, что мне приходится выбирать только один ответ.

Ответ №3:

Это захватит все W с одной или несколькими цифрами перед ним

Код:

 import re
text = "Fast charging 25W, USB Power Delivery 3.0, Fast Qi/PMA wireless charging 12W, Reverse wireless charging 4.5W"

pattern = '((d[.])?d [W])'
matches = [match.group() for match in re.finditer(pattern, text)]
print(matches)
 

Вывод:

 ['25W', '12W', '4.5W']
 

Ответ №4:

Другое решение с использованием numpy using char.endswith .

 import numpy as np

text = "Fast charging 25W, USB Power Delivery 3.0, Fast Qi/PMA wireless charging 12W, Reverse wireless charging 4.5W"
A = np.array(text.split(",")) 
v = np.char.endswith(A, 'W') 
A[v]
 

Вывод:

 array(['Fast charging 25W', ' Fast Qi/PMA wireless charging 12W',
   ' Reverse wireless charging 4.5W'], dtype='<U34')