Java 我可以确定由正则表达式模式匹配的第一个字符集吗?
我希望能够计算所有字符的集合,这些字符可以通过给定的Java 我可以确定由正则表达式模式匹配的第一个字符集吗?,java,regex,scala,automata,dfa,Java,Regex,Scala,Automata,Dfa,我希望能够计算所有字符的集合,这些字符可以通过给定的java.util.regex.Pattern实例作为字符串中的第一个字符进行匹配。更正式地说,给定DFA等价于某个正则表达式,我需要从开始状态开始的所有传出转换的集合 例如: Pattern p = Pattern.compile("[abc]def|daniel|chris|\\s+"); Set<Character> first = getFirstSet(p); 有什么想法吗?我很清楚,我可以自己构造DFA并以这种方式确定
java.util.regex.Pattern
实例作为字符串中的第一个字符进行匹配。更正式地说,给定DFA等价于某个正则表达式,我需要从开始状态开始的所有传出转换的集合
例如:
Pattern p = Pattern.compile("[abc]def|daniel|chris|\\s+");
Set<Character> first = getFirstSet(p);
有什么想法吗?我很清楚,我可以自己构造DFA并以这种方式确定相关状态,但我希望避免这种麻烦(请阅读:它对我来说不值得这么多)。请注意,我的宿主语言实际上是Scala,因此我可以访问所有的核心Scala库(不管它值多少)。我认为您可以解析正则表达式,并定义一些递归函数,以从左到右的方式对解析的正则表达式进行操作,从而建立这样一组第一 有些事情很简单:
- 顺序:first(r1r2)=first(r1)+(如果第一(r1)中的“”第一(r2)否则为空)
- 交替:第一(r1 | r2)=第一(r1)+第一(r2)
- 迭代:第一(r*)=第一(r)+”
- 字符:第一(c)=c
- CharacterClass:第一([c1 cn])=集合(c1,c2,…,cn)
将其扩展到正则表达式方言所知道的所有原语和特殊标志,这样就可以了 你可以递归地解决它
- 去掉括号并递归调用
- 在顶层拆分备选方案,并为每个部分递归调用
- 如果没有其他选择,
- 输出所有符号,从左起到第一个无可选符号
- 如果有字符组,则输出所有符号
所以我认为这确实是一个复杂的问题。是的,我考虑过了。这实际上与我自己构建DFA的前端是一样的。如果归结起来,也许我会这么做,但我更愿意找到一个更简单的解决方案。我不确定它比解析它(根据语言标准中的固定语法)和一些非常明显的递归要简单多少,但也许这只是我的编译结构注入了脑力,解析和递归遍历并不是很糟糕,我只是不喜欢为了得到第一个集合而不得不复制Java的正则表达式语义,我没有考虑否定类。考虑到Java使用UTF-8,第一组可能有几十万个大小。哎哟也许我会假设正则表达式可以匹配任何东西,并保持未优化状态……我只是想重写表达式-如果您可以构建一个只匹配输入表达式的第一个符号的表达式,那么您可以循环一些单个符号字符串,并测试派生表达式是否匹配。但是要获得所有字符,您必须在整个字符集上循环-Unicode需要大量的工作。我想不出一个方法来得到这样一个派生表达式。也许入侵regex实现并通过反射检查内部状态。但所有这些可能都会影响到自己编写regex实现。所以我没有(好的)想法。
{ 'a', 'b', 'c', 'd', ' ', '\n', '\r', '\t' }