如何在 Java 中构建正则表达式来检测字符串的空格或结尾?

Posted

技术标签:

【中文标题】如何在 Java 中构建正则表达式来检测字符串的空格或结尾?【英文标题】:How to build a Regex in java to detect a whitespace or end of a string? 【发布时间】:2016-02-10 10:55:44 【问题描述】:

我正在尝试构建一个正则表达式来查找和提取包含邮政信箱的字符串。 这里有两个例子:

    str = "some text p.o. box 12456 Floor 105 streetName Street"; str = "邮政信箱 1011"; str = "邮局信箱 12 楼 105 塔拉普萨街"; str = "leclair ryan pc p.o. Box 2499 8th floor 951 east byrd street"; str = "box 1 slot 3 building 2 136 harvey road";

这是我的模式和代码:

Pattern p = Pattern.compile("p.*o.*box \\d+(\\z|\\s)"); 
       Matcher m = p.matcher(str); 
       int count =0;
       while(m.find()) 
           count++;
           System.out.println("Match number "+count);
           System.out.println("start(): "+m.start());
           System.out.println("end(): "+m.end());
       

它适用于第二个示例并注意第一个示例! 如果将我的模式更改为以下:

模式 p = Pattern.compile("p.*o.*box \d+ ");

它仅适用于第一个示例。 问题是如何将正则表达式分组为字符串“\z”的结尾,将正则表达式分组为空格“\s”或“”?

新模式: 模式 p = Pattern.compile("(?i)((p.*o.box\s\w\s*\d*(\z|\s*)|(box\s *\w\s*\d*(\z|\s*)) ))");

【问题讨论】:

The code seems working. 如果查找“po box”之后的数字组,我希望看到像“p.*o.*box (\d+)”这样的正则表达式。我希望使用group 方法。 哦,我没有指出:要么我遗漏了一些东西,要么你不需要检测“空白或 eos”,如果你只是对数字进行分组。第一个非数字将结束该组。 @Wiktor 你是对的,它正在工作,问题是区分大小写! 所以,只需在模式中添加Pattern.CASE_INSENSITIVE 标志或预先添加(?i) 【参考方案1】:

您可以利用following code:

String str = "some text p.o. box 12456 Floor 105 streetName Street";
Pattern p = Pattern.compile("(?i)\\bp\\.?\\s*o\\.?\\s*box\\s*(\\d+)(?:\\z|\\s)"); 
Matcher m = p.matcher(str); 
int count =0;
while(m.find()) 
      count++;
      System.out.println("Match: "+m.group(0));
      System.out.println("Digits: "+m.group(1));
      System.out.println("Match number "+count);
      System.out.println("start(): "+m.start());
      System.out.println("end(): "+m.end());

要使模式不区分大小写,只需将Pattern.CASE_INSENSITIVE 标志添加到Pattern.compile 声明或将内联(?i) 修饰符预先附加到模式。

另外,.* 匹配除换行符以外的任何字符零次或多次,我猜你想选择匹配.。因此,您只需要 ? 量词并转义点以匹配文字点。请注意我如何使用(...) 将数字捕获到第 1 组(它称为捕获组)。匹配字符串结尾或空格的组位于 非捕获组 ((?:...)) 内,该组仅用于分组,而不用于将其值存储在内存缓冲区中。由于您想在那里匹配单词边界,我建议将(?:\\z|\\s) 替换为仅\\b

Pattern p = Pattern.compile("(?i)\\bp\\.?\\s*o\\.?\\s*box\\s*(\\d+)\\b"); 

【讨论】:

当我将它应用于大型数据集时,我面临着许多不同的情况。但是,我改进了我的模式,但仍然无法检测到所有情况,或者我提取了错误的文本部分。我还检查了您的模式,这表明很多改进仍然没有检测到所有情况。这是更多示例以及我的新模式: str = "post office Box 12 Floor 105 Tallapoosa Street"; str = "leclair ryan pc p.o. Box 2499 8th floor 951 East byrd Street"; str = "box 1 slot 3 building 2 136 harvey road";模式 p = Pattern.compile("(?i)(p.*o.*box\\s*\\w\\s*\\d*(\\z|\\s*))"); 对不起,评论里乱七八糟的,我会在问题中添加示例和模式 然后试试(?i)(?:\\bp(?:\\.|ost)?\\s*o(?:\\.|ffice)?\\s*)?box\\s*(\\d+)\\b 谢谢,这适用于新字符串,但由于数据集容易出错,我不想添加像“office”或“ost”这样的限制。 这些不是限制,这些是替代方法。如果您有“post office Box 456”,则需要允许匹配完整的单词。【参考方案2】:

您的正则表达式中有几个项目看起来需要工作。据我了解,您想提取 P.O.您提供的此类格式的字符串中的框号。鉴于此,以下正则表达式将完成您想要的,并提供以下解释。在此处查看实际操作:https://regex101.com/r/cQ8lH3/2

Pattern p = Pattern.compile("p\.?o\.? box [^ \r\n\t]+");

首先,对于转义序列,您只需要使用一个斜杠。此外,您必须避开这些点。如果您不转义点,正则表达式会将. 匹配为任何单个字符。 \. 将改为匹配点符号。

接下来,您需要将\. 后面的* quantifier 更改为?。为什么? * 符号将匹配零个或多个前面的符号,而 ? 量词将仅匹配一个或不匹配。

最后重新考虑如何匹配箱号。而不是匹配所有字符然后是空格,只需匹配不是空格的所有内容。 [^ \r\n\t]+ 将匹配所有非空格 ()、回车 (\r)、换行 (\n) 或制表符 (\t) 的字符。因此,它将消耗盒子编号并在遇到任何空白或文件结尾时立即停止。

其中一些更改可能不是让您的代码适用于您提供的示例所必需的,但它们是构建您想要的正则表达式的正确方法。

【讨论】:

你能告诉我更多关于正则表达式的信息吗,我一直很困惑 感谢@AlienHoboken!现在可以了,问题是区分大小写。无论如何,我必须使用两个斜杠,否则我会出错!

以上是关于如何在 Java 中构建正则表达式来检测字符串的空格或结尾?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测带有下划线的字符串的正则表达式模式

用java正则表达式检测字符串中是不是含有某字符

Oracle中如何用正则表达式检测某个字段是不是带有日文字符

如何检测两个正则表达式在它们可以匹配的字符串中是不是重叠?

JAVA基础之正则表达式

如何检测正则表达式中的下划线? [复制]