首页 > 解决方案 > 可用空间正则表达式选项未按预期工作

问题描述

我正在尝试使用正则表达式检测亵渎。但我想检测这个词,即使他们已经把“亵渎”这样的词隔开。但是,当使用“(?x)”选项时,它仍然不想检测。

我目前得到:

(?ix).*Bad Word.*

我试过使用http://www.rubular.com来调试表达式,但运气不好。

如果它有任何帮助,那就是在 Teamspeak Bot 中,我想踢用户,因为他们的名字中有被禁止的词。在配置中,它指的是http://docs.oracle.com/javase/1.5.0/docs/api/java/util/regex/Pattern.html我找不到与 (?) 选项相关的任何内容。

机器人本身可以在这里找到:https://forum.teamspeak.com/threads/51286-JTS3ServerMod-Multifunction-TS3-Server-Bot-(Idle-Record-Away-Mute-Welcome-)

标签: javaregex

解决方案


使用“(?x)”选项时,它仍然不想检测

(?x)是一个嵌入式标志选项(也称为内联修饰符/选项)启用该Pattern.COMMENTS选项,也称为自由间距模式,它启用正则表达式中的注释并使正则表达式引擎忽略模式内的所有常规空格。根据字符类中的自由间距

在自由间距模式下,正则表达式标记之间的空格将被忽略。空白包括空格、制表符和换行符。请注意,仅忽略标记之间的空格。a b cabc自由间距模式相同。但是\ d\d不一样。前者匹配 d,而后者匹配一个数字。\d是由反斜杠和"d". 用空格分解标记会给你一个转义的空格(它匹配一个空格)和一个文字“d”。

同样,不能分解分组修饰符。(?>atomic)(?> ato mic )和 相同( ?>ato mic)。它们都匹配相同的原子组。它们不一样(? >atomic)。后者是语法错误。分组修饰符是正则表达式语法中的?>单个元素,并且必须保持在一起。对于所有此类结构都是如此,包括lookaroundnamed groups等。

因此,要将模式中的单个空格与(?x)修饰符匹配,您需要对其进行转义:

String reg = "(?ix).*Bad\\ Word.*";   // Escaped space matches a space in free spacing mode
String reg = "(?ix).* Bad\\ Word .*"; // More formatting spaces, same pattern

请注意,您不能将空格放入字符类中以使其在 Java 正则表达式中有意义。见下文:

然而,Java 并不将字符类视为自由间距模式下的单个标记。Java 确实忽略了字符类中的空格、换行符和注释。所以在 Java 的 free-spacing 模式下,[abc]等同于[ a b c ].

此外,我认为您实际上想确保您的模式可以匹配可能包含换行符的完整字符串。这意味着,您需要(?s), Pattern.DOTALL, 修饰符:

String reg = "(?is).*Bad Word.*";

此外,要匹配任何空格,您可以依赖\s

String reg = "(?ix).*Bad\\sWord.*"; // To only match 1 whitespace
String reg = "(?ix).*Bad\\s+Word.*"; // To account for 1 or more whitespaces

推荐阅读