Java ';什么时候开始';在正则表达式中不匹配?

Java ';什么时候开始';在正则表达式中不匹配?,java,regex,Java,Regex,我遇到了以下问题(简化)。我写了以下内容 Pattern pattern = Pattern.compile("Fig.*"); String s = readMyString(); Matcher matcher = pattern.matcher(s); 在读取一个字符串时,匹配器无法匹配,即使它以“Fig”开头。我在字符串的下一部分找到了一个流氓字符。它的代码点值为1633 (int) charAt(i) 但与正则表达式不匹配。我认为这是由于输入过程中的某个地方使用

我遇到了以下问题(简化)。我写了以下内容

Pattern pattern = Pattern.compile("Fig.*");
String s = readMyString();
Matcher matcher = pattern.matcher(s);
在读取一个字符串时,匹配器无法匹配,即使它以“Fig”开头。我在字符串的下一部分找到了一个流氓字符。它的代码点值为1633

(int) charAt(i)
但与正则表达式不匹配。我认为这是由于输入过程中的某个地方使用了非UTF-8编码

他们说:

预定义字符类 . 任何字符(可能与行终止符匹配,也可能不匹配)

这可能不是严格意义上的字符,但仍然是字符串的一部分。如何检测此问题


更新:这是由于(字符)10这是不容易发现。我上面的诊断是错误的,下面的所有答案都与所问的问题相关,并且非常有用。

Java正则表达式中的
字符与除行终止符以外的任何字符匹配,除非在编译模式时使用标志
Pattern.DOTALL

为此,您将使用如下模式:

Pattern p = Pattern.compile("somepattern", Pattern.DOTALL);

检查这一点很容易:

import java.util.regex.*;

public class Test {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile(".");
        for (char c = 0; c < 0xffff; c++) {
            String text = String.valueOf(c);
            if (!pattern.matcher(text).matches()) {
                System.out.println((int) c);
            }
        }
    }
}
其中,10和13分别为“\n”和“\r”。133(U+0085)是“下一行”,8232(U+2028)是“行分隔符”,8233(U+2029)是“段落分隔符”

请注意:

  • 这不会测试基本多语言平面之外的任何Unicode字符
  • 它只使用默认选项
  • 这似乎与你对1633(U+0661)角色的体验相矛盾

关于使用正则表达式非打印字符,您可以阅读以下两篇文章:

  • 即使您完全使用UTF,也会有很多惊喜。

    根据,
    可以有3种稍有不同的解释,具体取决于标志

    默认情况下
    将在禁用模式和模式时排除(默认):

    行终止符是一个一个或两个字符的序列,用于标记输入字符序列行的结束。以下是公认的线路终端:

    • 换行符(换行符)字符(
      '\n'
    • 紧接着换行符(
      “\r\n”
      )的回车符
    • 独立的回车符(
      '\r'
    • 下一行字符(
      '\u0085'
    • 行分隔符(
      '\u2028'
      ),或
    • 段落分隔符(
      '\u2029'
    这意味着在这种情况下,
    相当于
    [^\n\r\u0085\u2028\u2029]

    当启用了
    UNIX\u行
    模式,但禁用了
    DOTALL
    模式时 当启用模式但禁用模式时,
    将仅排除
    \n
    。这意味着在这种情况下,
    相当于
    [^\n]

    如果模式被激活,则唯一识别的行终止符是换行符

    启用
    DOTALL
    模式时 如果启用模式,
    将匹配任何字符,无例外

    正则表达式
    匹配除行终止符以外的任何字符,除非指定了标志


    你能举一个由
    readMyString()
    返回的
    字符串的例子吗?不,因为我认为它会被剪切和粘贴损坏(有问题的字符不会打印),我用
    “Fig\u0661”
    试过,它匹配正确。@Howard是的-如果你自己构造字符串,它就可以工作。到1633,你是说1633(十进制)吗或者0x661(十六进制):?检查是一种方法,但是文档在这一点上应该足够清楚。@nhahdh:是的,这是公平的。查看哪些字符算作换行符很有用:)您还可以使用模式字符串开头的
    (?s)
    将选项表示为标志,如下所述:。如果使用更紧凑的语法,或者在我的例子中使用Scala,这可能会更方便。
    10
    13
    133
    8232
    8233