[英]delete first X words and delimiters of a string - with multiple delimiters
我有一个字符串,如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 ++]分隔符是空格,制表符和逗号。 其他所有东西(包括等号,减号等)都是一个单词的一部分(虽然如果有问题,我会很高兴,如果有必要,回答者会告诉我如何在将来添加新的分隔符)
您可以像这样定义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'
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
以下方法怎么样:
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
你可以使用re.sub()
:
>>> def remover(s, n):
... return re.sub(r'^(\s?\b\w+\b\s?){%s}'%n,'', s)
DEMO:
>>> 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'
@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!**
这似乎适用于您的测试用例:
>>> 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()
。
我认为这个方法非常简单,并且不使用正则表达式:
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)
很难确定你对“分隔符”和“单词”的定义是什么。 例如,在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:
但是=
怎么样? 是=
应该是一个“单词”或“分隔符”或什么? 如果规则不同,请告诉我们规则究竟是什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.