假设我有一个字符串,我想检查它是否以任何可能的(随机)顺序与另一个字符串匹配。例如,假设我有一个字符串 s
,我想检查它是否以随机顺序匹配 "ONE"
(== 以下之一:ENO|EON|NEO|NOE|OEN|ONE
,但不是 EEE;EEN;EEO;
等)
在更一般的描述中:我正在寻找一个正则表达式来以随机顺序匹配字符串,仅使用该字符串的给定字符(这意味着字符串本身可以包含重复的字符,例如 SEVEN
,但在随机匹配中应该恰好使用两个 E
,而不是多或少)。
我知道我可以使用文字 ENO|EON|NEO|NOE|OEN|ONE
来匹配 ONE
,对于 TWO
也是如此> 到 NINE
,但这太长了..
我也知道我可以匹配所有内容,包括重复的字符,例如 [ONE]{3}
,但它也会错误地匹配 EEE
、EEN
,等等。
我知道我也可以创建一个循环来生成所有这些不同的排列,并将它们与 |
分隔符附加在一起。我认为在这种情况下这也可能是一个有效的解决方案。但如果使用正则表达式可以实现这一点,我也想知道我自己的知识。哦,即使它有一个循环,我也不希望它太长(因为我实际上是因为代码高尔夫挑战而问这个问题,在这个挑战中,你需要用尽可能少的字节来解决某个挑战)。
最佳答案
您可以在前瞻中添加条件。对于一个:
\b(?=\w*O)(?=\w*N)(?=\w*E)[ONE]{3}\b
七人:
\b(?=\w*S)(?=\w*E\w*E)(?=\w*V)(?=\w*N)[SEVN]{5}\b
要提高大文本的性能,您可以测试模式开头的字母和长度:
\b(?=[ONE]{3}\b)(?=\w*O)(?=\w*N)\w*E\w*
或者:
\b(?=[SEVN]{5}\b)(?=\w*S)(?=\w*E\w*E)(?=\w*V)\w*N\w*
这样,包含其他字母的单词或长度不合适的单词就会很快被丢弃。
您还可以将效率较低的条件放在最后:
\b(?=[SEVN]{5}\b)(?=\w*S)(?=\w*V)(?=\w*N)\w*E\w*E\w*
最后,您还可以使用否定字符类来减少回溯:
\b(?=[SEVN]{5}\b)(?=[^\WS]*S)(?=[^\WV]*V)(?=[^\WN]*N)[^\WE]*E[^\WE]*E\w*
或使用其他字母:
\b(?=[SEVN]{5}\b)(?=[EVN]*S)(?=[SEN]*V)(?=[SEV]*N)[SVN]*E[SVN]*E\w*
关于java - 正则表达式以任何随机顺序完全匹配单词的字符,没有重复的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45633727/