java正则表达式,用于检查最后一行是否已取消转义%

lnvxswe2  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(218)

我需要检查最后一行。我有一个字符串,它将被tex编译器进一步处理。在这里,一行中的第一个%被视为注解,而该行的其余部分被编译器“看不到”。
但是第一个%有点棘手,因为它可能会被一个 \ 所以 \% 应该忽略。
所以基本上我想检查最后一行是否以注解结尾?
例如

(a) last line % now with comment
(b) last line with escaped \%  and not treated
(c) last line withouth any special chars
(d) last line terminates with %
(e) last line terminates with escaped \%
(f) beginning % but even escaped \% is ignored

为了检查,我需要阳性: a , d 以及 f 而其他的应该被忽略。
按照我的要求,到目前为止:

[^\n]*$

测试最后一行。很好,但现在我甚至不知道如何在最后一行匹配只是一个简单的问题 % . 我早就料到 (%)? 只有在 % 是可用的,但偶数(c)是正的,因为它匹配最后一行。
谁能帮我过滤一下 % 我在找什么?

2nc8po8w

2nc8po8w1#

你可以用消极的向后看来实现你想要的。
demo:https网址:regex101.com/r/orqrhv/1
图案: (?<!\\)% 更新1:为了确保只有我们匹配最后一行, atomic group 可以使用。
图案: (?>[\s\S]*\n).*(?<!\\)% 细节: [\s\S]*\n 将匹配所有字符直到最后一个 \n . 原子团, (?>..) 将防止发动机回溯。
成功匹配:https://regex101.com/r/orqrhv/2
匹配失败:https://regex101.com/r/orqrhv/4
注意:如果在输入文本的末尾有一个空的新行,比如https://regex101.com/r/orqrhv/3,它将不匹配。如果这需要匹配,那么我们需要使用负前瞻。
图案: (?>[\s\S]*\n(?<!$)).*(?<!\\)% . (?<!$) 确保 \n 不是紧跟在字符串末尾。

fcg9iug3

fcg9iug32#

你可以用

(?<!\\)(?:\\{2})*%[^\\%\r\n]*(?:\\[\w\W][^\\%\r\n]*)*\z

查看regex演示。
细节 (?<!\\) -没有 \ 允许直接位于当前位置的左侧 (?:\\{2})* -任何零个或多个双反斜杠(此模式和前面的模式是避免匹配 % 前面有转义反斜杠,不能只使用 (?<!\\) ) % -a % 烧焦 [^\\%\r\n]* -零个或多个字符 \ , % 以及cr和lf行尾符号 (?:\\[\w\W][^\\%\r\n]*)* -零次或多次出现 \\[\w\W] -任何逃逸的字符, \\ 比赛 \ 以及 [\w\W] 匹配任何字符(可以替换为 . 如果你加上 (?s) 模式开头的dotall inline embedded flag选项) [^\\%\r\n]* -任何零个或多个字符,除了 \ , % 以及cr和lf行结束符号。
在java中,使用如下模式

String text = "(a) last line % now with comment\n(b) last line with escaped \\%  and not treated\n(c) last line withouth any special chars\n(d) last line terminates with %\n(e) last line terminates with escaped \\%\n(f) beginning % but even escaped \\% is ignored";
Pattern p = Pattern.compile("(?<!\\\\)(?:\\\\{2})*%[^\\\\%\r\n]*(?:\\\\[\\w\\W][^\\\\%\r\n]*)*\\z");
Matcher m = p.matcher(text);
if (m.find()) {
  System.out.println("Match found!");
}
// => Match found!

请参见java演示。

相关问题