繁体   English   中英

删除字符串的前X个单词和分隔符 - 具有多个分隔符

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM