如何在Java中读取字符串的一部分

5

我有这个字符串:

<meis xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uri="localhost/naro-nei" onded="flpSW531213" identi="lemenia" id="75" lastStop="bendi" xsi:noNamespaceSchemaLocation="http://localhost/xsd/postat.xsd xsd/postat.xsd">

如何在JAVA中获取lastStop属性值?

这个正则表达式在http://www.myregexp.com/上测试成功。

但是当我在Java中尝试时,我没有看到匹配的文本,以下是我的尝试:

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class SimpleRegexTest {
    public static void main(String[] args) {
        String sampleText = "<meis xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" uri=\"localhost/naro-nei\" onded=\"flpSW531213\" identi=\"lemenia\" id=\"75\" lastStop=\"bendi\" xsi:noNamespaceSchemaLocation=\"http://localhost/xsd/postat.xsd xsd/postat.xsd\">";
        String sampleRegex = "(?<=lastStop=[\"']?)[^\"']*";
        Pattern p = Pattern.compile(sampleRegex);
        Matcher m = p.matcher(sampleText);
        if (m.find()) {
            String matchedText = m.group();
            System.out.println("matched [" + matchedText + "]");
        } else {
            System.out.println("didn’t match");
        }
    }
}

也许问题在于我在测试中使用了转义字符,但实际字符串内部没有转义。 更新 有人知道为什么在Java中使用时这不起作用吗?或者如何使其起作用?

问题在于第二个 ?(字符组后面的那个)。由于输入似乎是 XML,引号无论如何都不是可选项,因此删除它不是问题,并且可以使正则表达式起作用。 - Joachim Sauer
@Joachim Sauer 输入不是XML,而是XML文件的一部分,该文件已记录为字符串。 - Gandalf StormCrow
它是XML文件的一部分(我假设它是格式良好的),这意味着属性必须被引用。 - Joachim Sauer
@Joachim Sauer 那确实是真的。 - Gandalf StormCrow
2个回答

3
(?<=lastStop=[\"']?)[^\"]+

请再试一次,不要使用命名分组。 - Hun1Ahpu
@Hun1Ahpu 我该怎么做呢? - Gandalf StormCrow
对于 lastStop=123 id="1",它会捕捉到 123 id=,更不用说 uri="localhost/naro-nei?lastStop=4"。我相信 Java 有更好的 XML 能力。 - Kobi
还有一件事,在这个网站上的正则表达式是可以工作的,但在Java中出现语法错误。如何更正呢?String regex = "(?<=lastStop=["']?)[^"']*"; - Gandalf StormCrow
你需要转义引号:String regex = "(?<=lastStop=[\"']?)[^\"']*"; - Kobi
显示剩余2条评论

2
由于 [^\"']* 中的 *,它不能按照您的预期工作。回顾向后匹配在 lastStop=" 中的 " 之前匹配成功,因为引号是可选的:[\"']?。接下来的部分应该匹配零个或多个非引号字符,但由于下一个字符是引号,它将匹配零个字符。
如果您将那个 * 改为 +,则第二部分将无法在该位置匹配成功,强制正则表达式引擎向前移动一个位置。回顾向后将匹配引号,[^\"']+ 将匹配其后内容。然而,您真的不应该首先使用回顾向后进行此操作。通过捕获组,普通方式匹配整个序列并提取想要保留的部分会更容易些。
String sampleRegex = "lastStop=[\"']?([^\"']*)";
Pattern p = Pattern.compile(sampleRegex);
Matcher m = p.matcher(sampleText);
if (m.find()) {
    String matchedText = m.group(1);
    System.out.println("matched [" + matchedText + "]");
} else {
    System.out.println("didn’t match");
}

这也将使处理@Kobi提到的问题更加容易。您试图允许包含在双引号、单引号或无引号中的值,但是您的正则表达式过于简单。首先,带引号的值可以包含空格,但未带引号的值不能。为了处理这三种可能性,您需要 两个或三个 捕获组,而不仅仅是一个。


你的观点可能是正确的,但我真的不知道,但是你的正则表达式并没有起作用,请再试一下。我得到了这个结果 lastStop="bendi 而不是 bendi - Gandalf StormCrow
它对我有效。请注意,我调用的是m.group(1)而不是m.group() - Alan Moore
这两个调用之间有什么区别? - Gandalf StormCrow
group() 返回整个匹配结果,而 group(1) 返回第一个捕获组的内容。在这种情况下,只有一个捕获组:([^\"']*)。参考链接:http://java.sun.com/javase/6/docs/api/java/util/regex/Matcher.html#group%28int%29,http://www.regular-expressions.info/brackets.html - Alan Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接