我可以使一个正则表达式完全匹配一个类中的每个字符 - 即使字符在类中重复?
Posted
技术标签:
【中文标题】我可以使一个正则表达式完全匹配一个类中的每个字符 - 即使字符在类中重复?【英文标题】:Can I make a regex match each character in a class EXACTLY ONCE - even when characters REPEAT in the class? 【发布时间】:2020-09-28 01:21:05 【问题描述】:我正在尝试通过一组测试,以在 Java 中使用我的正则表达式查找字谜。 只有当输入字符串中的每个字符都只使用一次时,如果一个或多个字符在输入中出现多次,是否有办法使正则表达式匹配?
给定输入字符串terror
,我需要匹配rorret
,而不是rottet
。前两个单词完全共享所有字母,而第三个单词有三个“t”而不是三个“r”。
我目前使用的模式是(?i)^(?!terror)[terror]6
。
方法如下:
private String baseString;
public String isAnagram(String candidate)
Pattern p = Pattern.compile("(?i)^(?!"+baseString+")["+baseString+"]"+baseString.length()+"");
(p.matcher(candidate).matches()) ? return candidate: return "Not an anagram.";
我尝试过负前瞻:^(?!.*?([terror]).*?\1)(?!terror)[terror]6
虽然这可以确保每个字符至少使用一次,但它不能解释 baseString 和候选字符中的重复字母。
虽然我当然知道这可以通过编程方式解决,但稍微扩展模式以适应我需要的最后一个条件会更好。
【问题讨论】:
这是一个字谜问题,单纯的正则表达式可能无法提供解决方案。 以'terror'
为例,简单地对字母进行排序以形成数组["e", "o", "r", "r", "r", "t"]
然后对每个字谜候选者执行相同操作以查看它等于该数组会更容易。或者(看起来更有效),构造一个散列,给出'terror'
、"t"=>1, "e"=>1, "r"=>3, "o"=>1
中每个唯一字母的计数,然后对每个 anagram 候选者执行相同操作,以查看该散列是否结果。
好的,谢谢蒂姆和卡里。我现在将放弃正则表达式,伤心欲绝,并考虑构造一个哈希......我正在寻找一个有趣的解决方案和一个了解更多关于 Java 的机会,所以这似乎是合适的。
【参考方案1】:
就真正的正则表达式而言,底层的有限状态机需要 ~2ⁱ 状态(其中 i 是字符串中的字母数,假设它们都是不同的);它需要跟踪是否看到每个字母,以存储 i 位。
但是,我看不出如何用正则表达式语法来编写它;最好是受到它的启发,但手动实现它。搜索字符串中没有重复,可以只扫描一次文本(就像真正的正则表达式一样);不过,我看不出如何将其概括为具有重复字母的搜索字符串。
【讨论】:
嘿@sabik,谢谢您的意见。虽然性能对我的用例来说不是问题,但考虑机器正在完成的实际工作当然总是很有价值的。我也喜欢你所说的被正则表达式“启发”,但不使用它,我可能会那样做。不过,对于这种模式还是有点遗憾......:P以上是关于我可以使一个正则表达式完全匹配一个类中的每个字符 - 即使字符在类中重复?的主要内容,如果未能解决你的问题,请参考以下文章