我有一个字符串,例如manipulate widgets add,1,2,3
(抱歉,但我无法更改格式)。
我想删除前X个单词以及预先他们的任何分隔符。
我们以3为例,删除manipulate widgets add
并离开,1,2,3
或者,manipulate,widgets,add,1,2,3
删除两个字(manipulate,widgets
)并离开,add,1,2,3
我可以将字符串拆分为words = re.split('[' + delimiters + ']',inputString.strip())
的列表,但我不能简单地删除第一个X字
,比方说,
for i in range(1, numWorsdToRemove):
del words[0]
然后return ' '.join(words)
,因为它给了我1 2 3 4
。
我该怎么做并保留未删除单词的原始分隔符?
为了让它变得有趣,输入字符串可以在单词之间包含多个空格或制表符;只有一个逗号,但可能还有空格/取消它:
manipulate ,widgets add , 1, 2 , 3
请注意,单词不能保证是唯一的,所以我不能删除那些单词的索引,并使用它来返回位置子串。
[更新]我接受了'Kasramvd解决方案,但后来发现它没有正确处理remover('LET FOUR = 2 + 2', 2)
或remover('A -1 B text.txt', 2)
,所以现在我提供了解决方案。
[Update ++]分隔符是空格,制表符和逗号。其他所有内容(包括等号,减号等)都是一个单词的一部分(虽然如果有问题的话,我会很高兴,如果有必要的话会告诉我将来如何添加新的分隔符)
答案 0 :(得分:2)
您可以像这样定义一个RegEx
>>> import re
>>> regEx = re.compile(r'(\s*,?\s*)')
这意味着,一个可选的逗号后跟或前面有零个或多个空白字符。括号是创建一个匹配组,它将在拆分期间保留分隔符。
现在基于RegEx进行拆分,然后跳过您不想要的实际元素数量,以及与这些元素对应的分隔符数量(例如,如果您想跳过三个元素,那么将会是三个元素之间的两个分隔符。所以你想要从分割数据中删除前五个元素)并最终加入它们。
例如,
>>> def splitter(data, count):
... return "".join(re.split(regEx, data)[count + (count - 1):])
...
>>> splitter("manipulate,widgets,add,1,2,3", 2)
',add,1,2,3'
>>> splitter("manipulate widgets add,1,2,3", 3)
',1,2,3'
答案 1 :(得分:2)
s1='manipulate widgets add,1,2,3'
# output desired ',1,2,3'
s2='manipulate,widgets,add,1,2,3'
# delete two words (manipulate,widgets) and leave ,add,1,2,3
s3='manipulate ,widgets add , 1, 2 , 3'
# delete 2 or 3 words
import re
# for illustration
print re.findall('\w+',s1)
print re.findall('\w+',s2)
print re.findall('\w+',s3)
print
def deletewords(s,n):
a= re.findall('\w+',s)
return ','.join(a[n:])
# examples for use
print deletewords(s1,1)
print deletewords(s2,2)
print deletewords(s3,3)
输出:
['manipulate', 'widgets', 'add', '1', '2', '3']
['manipulate', 'widgets', 'add', '1', '2', '3']
['manipulate', 'widgets', 'add', '1', '2', '3']
widgets,add,1,2,3
add,1,2,3
1,2,3
答案 2 :(得分:1)
以下方法如何:
from itertools import islice
import re
text = "manipulate widgets,. add,1,2,3"
for x in islice(re.finditer(r'\b(\w+?)\b', text), 2, 3):
print text[x.end():]
这将显示:
,1,2,3
答案 3 :(得分:1)
您可以使用re.sub()
:
>>> def remover(s, n):
... return re.sub(r'^(\s?\b\w+\b\s?){%s}'%n,'', s)
样本:
>>> remover(s,3)
',1,2,3'
>>> remover(s,2)
'add,1,2,3'
>>> remover(s,1)
'widgets add,1,2,3'
>>> remover(s,0)
'manipulate widgets add,1,2,3'
答案 4 :(得分:1)
@original海报。请编辑测试用例,因为您的某些陈述似乎是矛盾的。您的第二个测试用例将逗号视为分隔符。但它也留下了逗号,这是第二个问题。它是一个分隔符,也可能不是。
# testcases : string , #of words to remove, desired answer
s=['manipulate widgets add,1,2,3',
'manipulate,widgets,add,1,2,3',
'manipulate ,widgets add , 1, 2 , 3',
'manipulate ,widgets add , 1, 2 , 3',
'LET X = 42',
'LET FOUR = 2 + 2',
'LET FOUR = 2 + 2',
'A -1 B text.txt'']
X= [3,2,2,3,3,2,3,2]
a= [',1,2,3',
'add,1,2, 3',
'add , 1, 2 , 3',
', 1, 2 , 3',
'42',
'= 2 +2',
'2 +2',
'B text.txt']
#Just to make it interesting, the input string can contain multiple spaces or tabs between words;
#only one comma, but that might also have spaces pre/suc-ceeding it
# <-- does that make the comma a word?
# only delimiters are space and tab, not commas
# <-- **does that make a single standing comma a word? **
# **2nd test case is contradictory to later statements, as comma is a delimiter here!**
答案 5 :(得分:1)
这似乎适用于您的测试用例:
>>> def remover(line, words):
... parsed = re.split('(\s*,{0,1}\s*)', line, maxsplit=words)
... return ''.join(parsed[-2:]).lstrip()
...
>>> remover('LET FOUR = 2 + 2', 2)
'= 2 + 2'
>>> remover('A -1 B text.txt', 2)
'B text.txt'
>>> remover('manipulate widgets add,1,2,3', 3)
',1,2,3'
>>> remover('manipulate,widgets,add,1,2,3', 2)
',add,1,2,3'
>>> remover('manipulate ,widgets add , 1, 2 , 3', 2)
'add , 1, 2 , 3'
如果与领先的空白有什么关系,那我就不清楚了。如果应该保留,则可以删除lstrip()
。
答案 6 :(得分:1)
我认为这种方法非常简单,并且不使用正则表达式:
def delete_leading_words(string, num_words, delimeters=' \t,'):
if num_words == 0:
return string
i = 0
while i < len(string) and string[i] in delimeters:
i += 1
while i < len(string) and string[i] not in delimeters:
i += 1
return delete_leading_words(string[i:], num_words-1, delimeters)
答案 7 :(得分:0)
很难确定您对“分隔符”和“单词”的定义是什么。例如,在A -1 B text.txt
情况下,-1
是否应被视为单词,或者是否应将字符串视为没有要删除的单词。这可以使用Kasramvd提供的正则表达式轻松定制。例如,如果你认为-1是一个“单词”,那么这基本上就是诀窍:
import re
def remover(s, n):
return re.sub(r'^(\s?\s*[^\s]+\s?){%s}' % n, '', s)
s = 'manipulate widgets add,1,2,3'
print('\nString is: {}\n'.format(s))
[print('Remove {}: '.format(x), remover(s, x)) for x in range(4)]
s = 'LET FOUR = 2 + 2 '
print('\nString is: {}\n', s)
[print('Remove {}: '.format(x), remover(s, x)) for x in range(7)]
s = 'A -1 B C text.txt'
print('\nString is: {}\n', s)
[print('Remove {}: '.format(x), remover(s, x)) for x in range(6)]
产生:
String is: manipulate widgets add,1,2,3
Remove 0: manipulate widgets add,1,2,3
Remove 1: widgets add,1,2,3
Remove 2: add,1,2,3
Remove 3:
String is: {}
LET FOUR = 2 + 2
Remove 0: LET FOUR = 2 + 2
Remove 1: FOUR = 2 + 2
Remove 2: = 2 + 2
Remove 3: 2 + 2
Remove 4: + 2
Remove 5: 2
Remove 6:
String is: {}
A -1 B C text.txt
Remove 0: A -1 B C text.txt
Remove 1: -1 B C text.txt
Remove 2: B C text.txt
Remove 3: C text.txt
Remove 4: text.txt
Remove 5:
但是=
呢? =
应该是“单词”还是“分隔符”或什么?如果规则不同,请告诉我们规则究竟是什么。