Pattern/Matcher group() 在 Java 中获取子字符串?
Posted
技术标签:
【中文标题】Pattern/Matcher group() 在 Java 中获取子字符串?【英文标题】:Pattern/Matcher group() to obtain substring in Java? 【发布时间】:2012-11-25 21:36:32 【问题描述】:更新:感谢所有精彩的回复!我尝试了许多不同的正则表达式模式,但不明白为什么 m.matches() 没有做我认为应该做的事情。当我改用 m.find() 并调整正则表达式模式时,我能够到达某个地方。
我想匹配 Java 字符串中的模式,然后使用正则表达式(如 Perl 的 $& 运算符)提取匹配的部分。
这是我的源字符串“s”:DTSTART;TZID=America/Mexico_City:20121125T153000
我想提取“America/Mexico_City”部分。
我认为我可以使用 Pattern 和 Matcher,然后使用 m.group() 进行提取,但它没有按我预期的那样工作。我尝试过使用不同的正则表达式字符串,唯一似乎在 m.matches() 上命中的是".*TZID.*"
,这是毫无意义的,因为它只返回整个字符串。有人可以启发我吗?
Pattern p = Pattern.compile ("TZID*:"); // <- change to "TZID=([^:]*):"
Matcher m = p.matcher (s);
if (m.matches ()) // <- change to m.find()
Log.d (TAG, "looking at " + m.group ()); // <- change to m.group(1)
【问题讨论】:
看起来像 ics (iCal) 文件中的一行 - 为什么不使用 ical4j.sourceforge.net 或等效项? 确实如此。我从 ical4j 开始,但在解析 ics 文件时出现错误,因此放弃了它。如果我需要更多功能而不仅仅是提取 DTSTART 行,我可能会再试一次。 【参考方案1】:星号前少了一个点。您的表达式将匹配任意数量的大写 D
s。
Pattern p = Pattern.compile ("TZID[^:]*:");
您还应该添加一个捕获组,除非您想捕获所有内容,包括"TZID"
和":"
Pattern p = Pattern.compile ("TZID=([^:]*):");
最后,您应该使用正确的 API 来搜索字符串,而不是尝试匹配整个字符串。
Pattern p = Pattern.compile("TZID=([^:]*):");
Matcher m = p.matcher("DTSTART;TZID=America/Mexico_City:20121125T153000");
if (m.find())
System.out.println(m.group(1));
这个prints
America/Mexico_City
【讨论】:
【参考方案2】:你使用了错误的模式,试试这个:
Pattern p = Pattern.compile(".*?TZID=([^:]+):.*");
Matcher m = p.matcher (s);
if (m.matches ())
Log.d (TAG, "looking at " + m.group(1));
.*?
将匹配一开始直到TZID=
的任何内容,然后TZID=
将匹配,一个组将开始并匹配所有直到:
,该组将在此处关闭,然后:
将匹配.*
将匹配字符串的其余部分,现在您可以在 group(1)
中获得所需的内容
【讨论】:
我删除了我几乎相同的答案以支持你的答案。你有一个更好的正则表达式。【参考方案3】:这应该很好用:
Pattern p = Pattern.compile("TZID=(.*?):");
Matcher m = p.matcher(s);
if (m.find())
String zone = m.group(1); // group count is 1-based
. . .
另一种正则表达式是"TZID=([^:]*)"
。我不确定哪个更快。
【讨论】:
【参考方案4】:为什么不简单地使用 split as:
String origStr = "DTSTART;TZID=America/Mexico_City:20121125T153000";
String str = origStr.split(":")[0].split("=")[1];
【讨论】:
非常优雅的解决方案。谢谢【参考方案5】:您使用m.match()
尝试匹配整个字符串,如果您将使用m.find()
,它将在内部搜索匹配项,我还改进了您的正则表达式以使用零宽度查找排除 TZID 前缀:
Pattern p = Pattern.compile("(?<=TZID=)[^:]+"); //
Matcher m = p.matcher ("DTSTART;TZID=America/Mexico_City:20121125T153000");
if (m.find())
System.out.println(m.group());
【讨论】:
以上是关于Pattern/Matcher group() 在 Java 中获取子字符串?的主要内容,如果未能解决你的问题,请参考以下文章