C# 正则表达式限制具有特定字母组合的单词(以任何顺序)

C# 正则表达式限制具有特定字母组合的单词(以任何顺序),c#,regex,C#,Regex,这个有点复杂,有点不适合我。我想对单词列表进行排序,并删除那些不包含特定字符集的单词,但是这些字符可以是任意顺序,其中一些可能比其他字符出现得更多 我希望正则表达式查找任何带有以下内容的单词: e0或1次 a0或1次 t0或1或2次 例如,以下方法可行: eatteatatettae 以下方法行不通 eatsteastatestttaaee Lookaround Regex对我来说是新的,所以我对语法不是100%确定(任何使用带有解释的Lookaround的答案都会很棒)。到目前为止,我最好的猜

这个有点复杂,有点不适合我。我想对单词列表进行排序,并删除那些不包含特定字符集的单词,但是这些字符可以是任意顺序,其中一些可能比其他字符出现得更多

我希望正则表达式查找任何带有以下内容的单词:

e
0或1次
a
0或1次
t
0或1或2次

例如,以下方法可行:

eat
teatatetta
e

以下方法行不通

eats
teas
tates
ttt
aa
ee

Lookaround Regex对我来说是新的,所以我对语法不是100%确定(任何使用带有解释的Lookaround的答案都会很棒)。到目前为止,我最好的猜测是:

Regex regex = new Regex(@"(?=.*e)(?=.*a)(?=.*t)");
lines = lines.Where(x => regex.IsMatch(x)).ToArray(); //'text' is array containing words
当然可以:

说明:

\b#单词的开头
(?:#组开始:任何一项匹配。。。
e#一个“e”,
(?!\w*e)#除非在同一个单词后面跟着另一个e,
|#或
t#a“t”,
除非。。。
(?:\w*t){2}#在同一个单词后面还有两个t,
)             # 
|#或
a#一个“a”
(?!\w*a)#除非在同一个单词后面跟着另一个a。
)+#根据需要重复(至少一个字母)
\b#直到我们到达世界的尽头。
测试一下


(为了简单起见,我使用了
\w
字符类;如果您想以不同的方式定义允许的“单词字符”,请相应地替换它)

这可能与其他字符相同,我还没有格式化这些字符

请注意,断言是强制匹配的,它们不能是可选的
(除非特别设置为可选,但为什么?)

这是可行的,解释在格式化的正则表达式中

更新
要使用空白边界,请使用以下命令:

格式:

 (?<! \S )
 (?!
      \w* 
      (?: e \w* ){2}
 )
 (?!
      \w* 
      (?: a \w* ){2}
 )
 (?!
      \w* 
      (?: t \w* ){3}
 )
 [eat]+ 
 (?! \S )
 \b                     # Word boundary
 (?!                    # Lookahead, assert Not 2 'e' s
      \w* 
      (?: e \w* ){2}
 )
 (?!                    #  Lookahead, assert Not 2 'a' s
      \w* 
      (?: a \w* ){2}
 )
 (?!                    #  Lookahead, assert Not 3 't' s
      \w* 
      (?: t \w* ){3}
 )
 # At this point all the checks pass, 
 # all thats left is to match the letters.
 # -------------------------------------------------

 [eat]+                 # 1 or more of these, Consume letters 'e' 'a' or 't'
 \b                     # Word boundary

我不认为正则表达式可以做你想做的事情(如果我错了,请纠正我!)。也许你可以将文本拆分成单词,然后计算每个单词中出现的每个字符的数量?然后如果你所做的计数的总和不等于单词的长度,那一定意味着有额外的非法字符漂浮在周围。这是一种可能性。我认为正则表达式可以处理类似的事情……然而r我可能也错了。就是这样,不是吗:D或with@NealR.OP words实际上是一个
字符串[]
。因此,您不必关心如何匹配单词,而是整个字符串。Tim的正则表达式唯一的问题是他使用
*
而不是
+
,从而允许它匹配空字符串。(参见演示中所有其他单词周围的垂直线?顺便说一句)单词边界和锚一样有效,因为有效的“单词”总是完全由字母组成。出于某种原因,这几乎有效,但并不完全有效。例如-
没有
没有
没有
正在通过。这是因为撇号吗?@BobbleBobble-你的正则表达式有效。我注意到的唯一区别是组中每个字母前面的字符。
我可能又漏掉了一些东西。例如:
(?!*?e)
vs
(?!\w*e)
我得到了与下面正则表达式相同的结果-像
这样的词没有
没有和
没有
通过(尽管这过滤了与另一个答案完全相同的单词数量)再次,我在这里扩展了我的正则表达式知识的边界,但这可能是因为撇号吗?@NealR-也添加了一个空白边界。这应该可以阻止那些
do's
not
被匹配。
 \b                     # Word boundary
 (?!                    # Lookahead, assert Not 2 'e' s
      \w* 
      (?: e \w* ){2}
 )
 (?!                    #  Lookahead, assert Not 2 'a' s
      \w* 
      (?: a \w* ){2}
 )
 (?!                    #  Lookahead, assert Not 3 't' s
      \w* 
      (?: t \w* ){3}
 )
 # At this point all the checks pass, 
 # all thats left is to match the letters.
 # -------------------------------------------------

 [eat]+                 # 1 or more of these, Consume letters 'e' 'a' or 't'
 \b                     # Word boundary