Я хочу удалить все цифры из строки, отличной от цифр, указанных в словаре. Я написал код, чтобы удалить его, но не получая ожидаемого результата. Пожалуйста, смотрите ниже:
mystr=" hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the ip address 122521587502. This string tells about deleting digits 502 600 765 from this."
myDict={'600','700'} # set()
# snippet to remove digits from string other than digits given in the myDict
Мое решение
for w in myDict:
for x in mystr.split():
if (x.isdigit()):
if(x != w):
mystr.replace(x," ")
Ожидаемый результат:
mystr=" hey I want to delete all the digits ex 600 700 m given in this string. And getting request from the
ip address . This string tells about deleting digits 600 from this."
Это еще одна альтернатива. Он добавляет пробелы в точки, но также удаляет номер после ip address
. Это не делается в других решениях из-за точки после номера.
import re
mystr= "hey I want to delete all the digits ex 600 502 700 m 8745 given in this
string. And getting request from the ip address 122521587502. This string
tells about deleting digits 502 600 765 from this."
myDict={'600','700'}
print(" ".join("" if (i.isdigit() and i not in myDict) \
else i for i in re.findall(r'(?:\w+|\d+|\S)', mystr)))
Выход:
hey I want to delete all the digits ex 600 700 m given in this string . And
getting request from the ip address . This string tells about deleting digits
600 from this .
PS: Существует ужасная альтернатива для исправления пробелов точек:
print("".join("" if (i.isdigit() and i not in myDict) \
else i if i == '.' or i == ',' \
else ''.join([' ', i]) for i in re.findall(r'(?:\w+|\d+|\S)', mystr))
.strip())
Что дает результат:
hey I want to delete all the digits ex 600 700 m given in this string. And
getting request from the ip address. This string tells about deleting digits
600 from this.
"".join("" if (i.isdigit() and i not in myDict) or re.search(r'^(?=.*[a-zA-Z])(?=.*[0-9])', i) else i if i == '.' or i == ',' else ''.join([' ', i]) for i in re.findall(r'(?:\w+|\d+|\S)', mystr)).strip()
Это один из подходов.
Пример:
import string
mystr= "hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the ip address 122521587502. This string tells about deleting digits 502 600 765 from this."
mySet={'600','700'}
rep = lambda x: x if x in mySet else None
print( " ".join(filter(None, [rep(i) if i.strip(string.punctuation).isdigit() else i for i in mystr.split()])) )
Выход:
hey I want to delete all the digits ex 600 700 m given in this string. And getting request from the ip address This string tells about deleting digits 600 from this.
In [1]: mystr=" hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the ip address
...: 122521587502. This string tells about deleting digits 502 600 765 from this."
...: myDict={'600','700'}
сначала вы можете подготовить данные для удаления:
...: mystr_l = mystr.replace('.', "").split()
...: to_remove = sorted(list({x for x in set(mystr_l) if x.isdigit() and x not in myDict}))
...:
...: print(to_remove)
['122521587502', '502', '765', '8745']
и удалить его из строки:
In [4]: for x in to_remove:
...: mystr = mystr.replace(x, " ")
...:
мой результат:
In [6]: print(mystr)
hey I want to delete all the digits ex 600 700 m given in this string. And getting request from the ip addres . This string tells about deleting digits 600 from this.
И некоторые испытания производительности:
def replace_digits(src_string, exclude_list):
result = src_string
string_l = src_string.replace('.', "").split()
to_remove = sorted(list({x for x in set(string_l) if x.isdigit() and x not in exclude_list}))
for x in to_remove:
result = result.replace(x, "")
return result
import re
def reg(src_string, exclude_list):
return " ".join("" if (i.isdigit() and i not in exclude_list) \
else i for i in re.findall(r'(?:\w+|\d+|\S)', src_string))
тесты:
In [8]: %timeit replace_digits(mystr, mySet)
11.3 µs ± 31.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [9]: %timeit reg(mystr, mySet)
...:
25.1 µs ± 21.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Вы можете использовать простой код, подобный этому, только с логической логикой и основными функциями строковых манипуляций.
mystr= "hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the ip address 122521587502. This string tells about deleting digits 502 600 765 from this."
myDict={'600','700'}
print( " ".join(c if not(bool(c.isdigit()) ^ bool(c in myDict)) else "" for c in mystr.split()) )
Но проблема с этим заключается в том, что в приведенном выше примере это не будет учитывать граничные цифры, которые поставляются с полной остановкой или другим специальным символом, например 122521587502.
. Итак, если вам все же нужно рассмотреть их, вы можете использовать настраиваемую функцию с сопоставлением шаблонов регулярных выражений вместо isdigit()
и написать немного сложный код для получения желаемого результата. Вот пример для рассмотрения чисел end bu fullstop и запятой.
^[0-9]*[\,\.]?$
Может использоваться как шаблон регулярного выражения для соответствия описанному выше сценарию. (вы можете использовать этот инструмент, чтобы легко отлаживать шаблоны регулярных выражений). Таким образом, фрагмент кода выглядит следующим образом:
import re
isNum = lambda c: True if re.match("^[0-9]*[\,\.]?$",c) else False
func = lambda c: True if re.compile("[\,\.]").split(c) in myDict else False
print(" ".join(c if not(isNum(c) ^ func(c)) else "" for c in mystr.split()))
Вам не нужно усложнять себя. Просто убедитесь, что mySet
- это словарь, выполнив dict(zip(mySet, mySet))
, затем используйте это для замены:
import re
mySet1 =dict(zip(mySet, mySet))
re.sub("\\d+", lambda x:mySet1.get(x.group()), mystr)
Out[604]: 'hey I want to delete all the digits ex 600 700 m given in this string.
And getting request from the ip address . This string tells about
deleting digits 600 from this.'
Вы можете сделать это с помощью re.sub
. Сопоставьте любой номер и используйте вызываемый заменитель, чтобы отфильтровать только те числа, которые не желательны.
Используя set
для хранения последовательностей цифр, которые вы хотите сохранить, позволяет выполнять поиск O (1) по мере прохождения строки.
import re
def remove_numbers(s, keep=None):
if keep:
keep = set(str(x) for x in keep)
return re.sub(r'\b\d+\b', lambda m: m.group() if m.group() in keep else '', s)
else:
# Shortcircuit the use of a set if there is no sequence to keep
return re.sub(r'\b\d+\b', '', s)
allowed = {600, 700}
s = 'I want to delete this: 100 200. But keep this: 600 700'
print(remove_numbers(s, allowed))
I want to delete this: . But keep this: 600 700
Это показывает комбинированный алгоритм предварительной обработки и удаления цифр. Эта программа также обрабатывает 122521587502.
и регистр 12.5
если они находятся во входной строке
exclude_set = {'600', '700'}
mystr=' hey I want to delete all the digits ex 600 502 700 8745 given in this string. And getting request from the ip address 122521587502. 12.5 This string tells about deleting digits 502 600 765 from this.'
# Pre-process the string converting all whitespaces to single spaces
mystr = " ".join(mystr.split())
# Check if the word is both a digit and to be excluded
# Also catch any floats and full-stops
mystr_list = mystr.split()
for word in mystr_list:
if word.replace('.', '').isdigit() and word not in exclude_set:
# Replace word or remove digit
if word.endswith('.'):
mystr_list[mystr_list.index(word)] = '.'
else:
mystr_list.remove(word)
# Combine the list to form your string
mystr = ' '.join(mystr_list)
print (mystr)