除非单词首字母是元音,否则删除所有元音。

3
我正在尝试删除字符串中元音的出现次数,除非它们是单词开头。所以例如输入 "The boy is about to win" 应该输出 Th by is abt t wn。这是我目前的代码。任何帮助都将不胜感激!
def short(s):
vowels = ('a', 'e', 'i', 'o', 'u')
noVowel= s
toLower = s.lower()
for i in toLower.split():
    if i[0] not in vowels:
        noVowel = noVowel.replace(i, '')        
return noVowel

1
修正你的缩进。哪一部分不起作用? - Ignacio Vazquez-Abrams
同时也不要忘记“y”是一个元音字母,除了通常在单词开头时。在“boy”中的“y”是双元音的一部分。 - Dmitri
6个回答

6

一种方法是使用正则表达式替换不在单词边界前的元音字母。此外,如果您的代码需要处理各种类型的标点符号来处理任意文本,您可能还需要考虑一些更有趣的测试用例。

import re
s = "The boy is about to win (or draw). Give him a trophy to boost his self-esteem."
rgx = re.compile(r'\B[aeiou]', re.IGNORECASE)
print rgx.sub('', s)  # Th by is abt t wn (or drw). Gv hm a trphy t bst hs slf-estm.

正则表达式似乎是这种问题的非常合适的解决方案,+1。 - Chris Cirefice

1

尝试:

>>> s = "The boy is about to win"
>>> ''.join(c for i, c in enumerate(s) if not (c in 'aeiou' and i>1 and s[i-1].isalpha()))
'Th by is abt t wn'

工作原理:

上述内容的关键部分是生成器:

c for i, c in enumerate(s) if not (c in 'aeiou' and i>1 and s[i-1].isalpha())

生成器的关键部分是条件:

if not (c in 'aeiou' and i>1 and s[i-1].isalpha())

这意味着除非它们是元音字母并且不在单词的开头,否则s中的所有字母都包括在内;或者它们被一个非字母字符所隔开,并且这也意味着它们位于单词的开头。

for循环重写

def short(s):
    new = ''
    prior = ''
    for c in s:
        if not (c in 'aeiou' and prior.isalpha()):
            new += c
        prior = c
    return new

这很好用!但我没有太多这个?有没有一种方法可以像我做的那样,将其放入包含for和if的表单中? - sm15
这种情况处理不了,即以元音开头的单词前面没有空格:s = “The boy is about to win (or draw)”。 对于 OP 的数据可能不是问题。 - FMc
@sm15 我添加了一个循环版本。 - John1024
@FMc 很好的建议。我修改了答案以更好地定义一个词。 - John1024

0
你可以在字符串的其余部分(忽略第一个字符)使用正则表达式。
import re
s = 'The boy is about to win'
s = s[0] + re.sub(r'[aeiou]', '', s[1:])
print s # Th by s bt t wn

0
使用正则表达式:
import re

re.sub("(?<!\b)[aeiouAEIOU]", '', s)

0

通过 re.sub。

>>> import re
>>> s = "The boy is about to win"
>>> re.sub(r'(?i)(?<=\S)[aeiou]', r'', s)
'Th by is abt t wn'

\S 匹配任何非空格字符。


0
>>> re.sub('(?<=\w)[aeiou]','',"The boy is about to win")
'Th by is abt t wn'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接