正则表达式在代号一中一次只能找到一个结果

Regex only found one result at a time in Codename One

我们正在尝试使用简单的正则表达式在模板字符串中查找一些标签。正则表达式就是 <[^<>]*>,因为我们的标签就像 <document:name>

我们在一些测试网站上尝试过,例如 Regex101 和 CodenameOne。所有工作都按预期进行,我们的标签被检测到,但是在 CN1 中,正则表达式一次只匹配一个标签,尽管 RE API 使用 int 来 select 匹配字符串。

是否要设置标志或其他内容以进行多次匹配?

我们有一个解决方法,如测试代码所示,但我们更愿意以正确的方式使用 API。

这是我们用于正则表达式的测试代码:

Form hi = new Form("Regex Tester", new BorderLayout());
Button test = new Button("Test RE");
TextField regex = new TextField("<[^<>]*>");
TextArea testString = new TextArea("Partner : <partner:label> \r\n" + 
        "Contact : <contact:lastname> static text with < <contact:firstname>");
Container results = new Container(BoxLayout.y());
Container north = BoxLayout.encloseY(regex, testString, test);

hi.add(BorderLayout.NORTH, north).add(BorderLayout.CENTER, results);

test.addActionListener(e->{
    results.removeAll();
    RE r = new RE(regex.getText());

    if(r.match(testString.getText()))
    {
        results.add(new Label("Regex matched !"));
        results.add(new Label("Results found : " + r.getParenCount()));
        for(int i = 0; i < r.getParenCount(); i++)
            results.add(new Label("" + r.getParen(i)));

        // Since it catches only one string at a time, here is a workaround
        results.add(new Label("======= V2 ======="));

        String testStr = testString.getText();
        int index = 0;
        int trueCount = 0;
        while(r.match(testStr, index))
        {
            results.add(new Label("Results found : " + r.getParenCount()));
            for(int i = 0; i < r.getParenCount(); i++)
            {
                results.add(new Label("" + r.getParen(i)));
                trueCount++;
            }
            index = r.getParenEnd(r.getParenCount() -1);
        }
        results.add(new Label("True count : " + trueCount));
    }
    else
        results.add(new Label("Regex didn't match..."));
    hi.forceRevalidate();
});

hi.show();

这是屏幕上显示的结果 "log":

正如您在绿色部分看到的,API 确实只找到了一个结果,但应该找到三个,如解决方法红色部分所示。

我想你误解了API。老实说,我不太确定我自己是否理解 API,但似乎 getParenCount() 不是那样工作的。

API 的 JavaDoc 说:"Returns the number of parenthesized subexpressions available after a successful match."

我猜这意味着:

<partner:label1 <partner:label2> <partner:label3>>

所以当它returns label1 应该是2。不过这个有点猜测。

经过一些关于正则表达式的研究和学习,我明白了 API 是如何工作的。

"Parenthesized subexpressions" 指的是捕获组,当我问这个问题时我什至不知道它的存在。所以它与结果无关,除了第一个捕获组总是完全匹配。

RE API 似乎无法一次捕获多个匹配项,看来我认为的解决方法实际上是从字符串中获取所有匹配项的正确方法,除了如果我们只想要匹配,我们需要用索引 0.

调用 getParen()

如果我对值使用正则表达式 (\w+ (\d+)) :

Jan 1987
May 1969
Aug 2011

这将是结果:

所以 API 完全可以工作,我只需要在我们的内部库中添加一些辅助方法以便更容易地使用它。如果我有时间,也许我会尝试为 RE 编写更好的文档。就像现在一样,对于不精通正则表达式恕我直言的开发人员来说,它几乎无法理解。

感谢 Shai 为我指明了正确的方向!