我需要一个正则表达式,如果之前已经捕获了 token 的一部分,它将忽略该 token 。
示例
var bold, det, bold=6, sum, k
此处,bold=6
应被忽略,因为 bold
已被捕获。
此外,在进行任何匹配之前,var
必须存在,最后一个标记 k
后面不应跟逗号。只有 var
中的变量和最后一个标记 k
后面应该跟逗号。
另一个例子
var bold=6, det, bold, sum, k
这里,det
后面的bold
应该被忽略,因为bold=6
已经被捕获。
我尝试使用此模式(?:\\bvar\\b|\\G)\\s*(\\w+)(?:,|$)
,但它没有'不要忽视已经重复的内容。
最佳答案
取决于您需要获取哪些信息,您可以尝试使用:
仅在 Java 中工作的解决方案,将为您提供变量名称和启动 和结束语:
(?<=var.{0,999})(?<!=)(?!var\b)\b(?<var>\w+)\b(?<!var.{1,999}(?=\k<var>).{1,999}(?=\k<var>).{1,999})
它使用了Java正则表达式的丑陋但非常有效的功能:间隔 (
x{min,max}
) 处于回溯状态。只要你使用间隔 最小和最大长度,您可以在 Java 正则表达式中使用它。所以与其 的.*
例如,您可以使用.{0,999}
。如果有的话就会失败 需要比 999 更多的字符,你可以使用更大的数字,但我 认为在这种情况下没有必要。命名组<var>
这里是可选的,您可以在代码中用普通组替换它。Java 实现:
public class Test{ public static void main(String[] args){ String test = "var bold, det, bold=6, sum, k\n" + "var foo=6, abc, foo, xyz, k"; Matcher matcher = Pattern.compile("(?<=var.{0,999})(?<!=)(?!var)\\b(?<var>\\w+)\\b(?<!var.{1,999}(?=\\k<var>).{1,999}(?=\\k<var>).{1,999})").matcher(test); while(matcher.find()){ System.out.println(matcher.group("var") + "," + matcher.start("var") + "," + matcher.end("var")); } } }
带有输出(变量名称、开始索引、结束索引):
bold,4,8 det,10,13 sum,23,26 k,28,29 foo,34,37 abc,41,44 xyz,51,54 k,56,57
正则表达式的解释:
-
(?<=var.{0,999})
- 前面必须有文本var
后跟任何
字符数,但不换行, -
(?<!=)
- 前面不应有等号,以避免将变量名称和值匹配为不同的匹配项, -
(?!var\b)
- 后面不能跟var
单词,以避免匹配该单词, -
\b(?<var>\w+)\b
- 单独的单词,捕获到<var>
组, -
(?<!var.{1,999}(?=\k<var>).{1,999}(?=\k<var>).{1,999})
- 匹配的单词前面不能有var
单词后跟一些字符,包括捕获的单词,后跟一些字符,再次包括捕获的单词,
但正如我所写,它只能在 Java 中运行。
如果您只需要变量名称,可以使用:
(?<=var\s|\G,\s)(?<var>\w+)(?=,|$)|(?<=var\s|\G,\s)(?<initialized>[^,\n]+)
获取没有重复的变量名称。但如果你想要 开始/结束索引,它将捕获到组中第二次出现的 变量名重复。
关于java - 正则表达式忽略已声明的变量初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32667643/