【问题标题】:Question about Java regex关于Java正则表达式的问题
【发布时间】:2009-04-22 11:49:14
【问题描述】:

我从数组列表中得到一个字符串:

array.get(0).toString()

给出 TITLE = "blabla"

我想要字符串 blabla,所以我试试这个:

Pattern p = Pattern.compile("(\".*\")");
Matcher m = p.matcher(array.get(0).toString());
System.out.println("Title : " + m.group(0));

不起作用:java.lang.IllegalStateException: No match found

我也试试:

Pattern p = Pattern.compile("\".*\"");
Pattern p = Pattern.compile("\".*\"");  
Pattern p = Pattern.compile("\\\".*\\\"");

我的程序中没有任何匹配项,但所有模式都适用于 http://www.fileformat.info/tool/regex.htm

有什么想法吗?提前致谢。

【问题讨论】:

    标签: java regex


    【解决方案1】:

    几点:

    Matcher#group 的 Javadoc 声明:

    IllegalStateException - 如果尚未尝试匹配,或者之前的匹配操作失败

    即在使用组之前,必须先使用m.matches(匹配整个序列),或者m.find(匹配一个子序列)。

    其次,您实际上想要m.group(1),因为m.group(0) 是整个模式。

    实际上,这在这里并不重要,因为所讨论的正则表达式以捕获括号开始和结束,因此 group(0) 与 group(1) 是相同的字符串,但如果你的正则表达式看起来像:"TITLE = (\".*\")"

    示例代码:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import org.junit.Test;
    
    @SuppressWarnings("serial")
    public class MatcherTest {
    
        @Test(expected = IllegalStateException.class)
        public void testIllegalState() {
            List<String> array = new ArrayList<String>() {{ add("Title: \"blah\""); }};
            Pattern p = Pattern.compile("(\".*\")");
            Matcher m = p.matcher(array.get(0).toString());
            System.out.println("Title : " + m.group(0));
        }
    
        @Test
        public void testLegal() {
            List<String> array = new ArrayList<String>() {{ add("Title: \"blah\""); }};
            Pattern p = Pattern.compile("(\".*\")");
            Matcher m = p.matcher(array.get(0).toString());
            if (m.find()) {
                System.out.println("Title : " + m.group(1));
            }
        }
    }
    

    【讨论】:

    • “你的正则表达式必须匹配整个字符串”——这就是matches()find()之间的区别,所以你的前两点并不像你暗示的那么明显。
    【解决方案2】:

    您需要首先在 Matcher 实例上调用 find()matches():它们实际上执行正则表达式并返回它是否匹配。然后只有匹配了才可以调用方法来获取匹配组。

    【讨论】:

    • 在这种情况下,您要调用的是 find()。
    • 没错。因为这是一个可疑的猜测,如果您已经编译了一个模式并为给定的字符串创建了一个“匹配器”,那么您仍然希望 find 该字符串中的任何内容。 (如果您只想知道某些东西是否 matches 模式,我不明白您为什么需要 Matcher 并且 Pattern 不能只告诉您它本身。 ) 通过冗长来拯救世界....
    • 如果你想要更短的代码,你可以简单地写 Pattern.matches("regex", input)。如果您希望为多个匹配项只编译一次模式,您需要做更多,是的。您似乎在抱怨没有 pattern.matches(CharSequence) 便利实例方法。毕竟,你可能会多次调用 matcher.find() 来查找多个匹配项,这与执行 matcher.matches() 或 matcher.lookingAt() 有很大不同。
    【解决方案3】:

    您是否在字符串中包含双引号 (")?

    您的所有正则表达式都已转义 "s,并且仅当列表中的字符串包含双引号字符时才会匹配。

    【讨论】:

      猜你喜欢
      • 2019-08-27
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多