正则表达式 - 匹配句子中除每个单词的第一个字母以外的所有内容

7

我几乎找到了答案,但我缺少一些东西,希望有人能帮助我。

我需要一个正则表达式,它将匹配句子中每个单词的第一个字母以外的所有字母。然后,我需要用正确数量的星号替换匹配的字母。例如,如果我有以下句子:

There is an enormous apple tree in my backyard.

我需要得到这个结果:

T**** i* a* e******* a**** t*** i* m* b*******.

我已经想出了一个几乎能够实现这个目标的表达式:
(?<=(\b[A-Za-z]))([a-z]+)

使用上面的例句,这个表达式给了我:
T* i* a* e* a* t* i* m* b*.

如何获得正确数量的星号?

谢谢。


1
你是否有特定的原因需要使用正则表达式?根据你所编写的编程语言,你可以使用子字符串替换来达到相同的效果。 - jerluc
4个回答

17

试试这个:

\B[a-z]

\B\b的反义词 - 它匹配没有单词边界的地方 - 当我们看到一个字母跟在另一个字母后面时。

您的正则表达式正在用单个星号替换整个单词的尾部 - [a-z]+,您应该逐一替换它们。如果您想让它工作,则应该匹配单个字母,但要检查其后面是否有单词(这有点无意义,因为您可以检查单个字母 (?<=[A-Za-z])[a-z]):

(?<=\b[A-Za-z]+)[a-z]

(请注意,最后一个正则表达式中有一个可变长度的后置断言,在大多数正则表达式引擎中并没有实现)


2
这里最短的正则表达式可能是\B\w,但\w会添加大写字母和下划线。 - Kobi
2
(?<=\b[A-Za-z]+) 在除了 .NET 和 JGSoft 之外的任何语言中都不起作用。你第一次就做对了。 - Alan Moore
@Alan - 很好的观点。我已经加了一个警告。无论如何,我确实说过这是相当无意义的 :) - Kobi
根据正则表达式的风格和您是否计划在a和z之间匹配非重音字母以外的其他字符,您可能想要使用\p{L}[^\W\d_]代替[a-z] - Tim Pietzcker
如果你有像“杰克的牙刷”这样的东西,那该如何处理呢? - Nathan Arthur
1
@NathanArthur - 这是一个好问题...更难的问题是什么是单词?上面的模式假设一个单词由字母数字字符组成,这是错误的。事实上,我不认为我可以通过简单的模式可靠地解决这个问题——有太多的边缘情况。不过,对于你的问题:在.Net中,您可以将撇号添加到上面的模式中:(?<=\b[A-Za-z']+)[a-z]。在其他版本中,我认为 (?<=\B|\b')[a-z] 可以工作。无论哪种方式,都需要一些思考。 - Kobi

3
你可以试试这个
\B\w

这将替换除每个单词的首字母外的所有字符

从这个==Hello==World==变成==H****==W****==


0

这是一个旧问题。由于其他答案似乎不能完全或清晰地解决此问题,因此我添加了一份答案。最简单的正则表达式是 /(\B[a-z])/g。这里添加了 'g' 作为全局标志,因此单个字符搜索将在整个字符串中重复执行。

string = "There is an enormous apple tree in my backyard."
answer = string.replace(/\B[a-z]/g, "*");

string = "There is an enormous apple tree in my backyard."
$("#stringDiv").text(string);

answer = string.replace(/\B[a-z]/g, "*");
$("#answerDiv").text(answer);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="stringDiv"></div>
<div id="answerDiv"></div>


0

可以尝试这个:

(\w{1})\w*

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