为什么奇怪?它按预期工作,可能是由于您作为第二个参数传递的标志。
让我们看看你的模式: -
".*(?<!S)\\.a\\s*\\(\\s*\\)\\s*$"
您的模式将匹配没有S
before的字符串.a
。从您的模式的以下部分可以清楚地看到这一点。
(?<!S)\\.a // Match if `.a` is not preceded by `S`.
现在,当您使用 时Pattern.CASE_INSENSITIVE
,此条件将同时检查s
和S
,之前.a
和如果其中任何一个存在,它将不匹配。所以你的模式从字面上变成: -
(?<![sS])\\.a // Match if `.a` is not preceded by `S` or `s`.
现在,在你的字符串中: -
"attributes.a()"
你有小s
前.a
。因此,您的代码中的模式将返回true
此字符串,并启用不区分大小写标志。
仅供参考,您也可以使用(?i)
标志而不是传递第二个参数Pattern.CASE_INSENSITIVE
来查看相同的效果。所以下面的模式和你的一样:-
Pattern p = Pattern.compile("(?i).*(?<!S)\\.a\\s*\\(\\s*\\)\\s*$");
using 的好处(?i)
是,你可以用它来制作你的 pattern 的一部分CASE_INSENSITIVE
。例如,如果您希望只检查(?<!S)
,但以下字符串可以是.a
or .A
,那么您可以(?i)
在之前使用.a
:-
Pattern p = Pattern.compile(".*(?<!S)(?i)\\.a\\s*\\(\\s*\\)\\s*$");
^^^
现在,标志后的整个模式(?i)
将以方式匹配CASE_INSENSITIVE
。
另外,请注意,正如评论中指出的那样,您实际上并不需要在这里进行后视或不区分大小写的匹配。如果你的信只应该是.你可以简单地[^S]
使用. 因为后视和不区分大小写会带来一些性能差异。因此,您可以简单地将模式更改为: -[aA]
a
Pattern p = Pattern.compile(".*[^S][.][aA][ ]*[(][ ]*[)][ ]*$");
我还将反斜杠替换为character class
. 我更喜欢使用它,而不是双重转义元字符。但这只是口味问题。你可以使用任何你喜欢的东西。