Java正则表达式求助

3

嘿,我一直在苦苦挣扎这个正则表达式,现在已经没有思路了。我有这些类型的字符串(并不是全部,只有这两种类型),我需要提取在th标签之间的部分。

<th class="tip" title='manje'>manje</th>
<th class="tip" title='ne d.'>ne d.</th>
<th class="tip" title='manje'>manje</th>
<th class="tip" title='točno'>točno</th>
<th class="tip" title='više'>više</th>
<th class="tip" title='m./t.'>m./t.</th>
<th class="tip" title='v./t.'>v./t.</th>
<th class="tip">daje</th>
<th class="tip">X2</th>
<th class="tip">12</th>

我尝试了一些组合,但只有在th标签中没有"title"属性时才能获取值。
这个模式只会提取内容,如果th标签中没有"title"属性:
Pattern pattern = Pattern.compile("<th class=\"tip\"[\\s*|[.]{0,20}]>(.*?)\\s*</th>");

这个也一样:

这里还有:

Pattern patternType = Pattern.compile("<th class=\"tip\"[\\s*|[.]{0,20}]>(.*?)\\s*</th>");

有什么建议吗?谢谢


哪一个起作用了?请给那个打分。 - Bohemian
小心使用 "[]",它定义了要匹配的单个字符。我不确定它实际上是在尝试匹配什么 "[.]"。 - toto2
由于您正在读取XML,因此最好使用dom和sax实用程序,这可能更合适。它们是Java SE基本包的一部分。 - toto2
5个回答

5

正则表达式并不适用于所有情况。请使用Jsoup代替:

package so6235727;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class PrintContent {

  private static final String html = //
      "<th class=\"tip\" title='manje'>manje</th>\r\n" + //
      "<th class=\"tip\" title='ne d.'>ne d.</th>\r\n" + //
      "<th class=\"tip\" title='manje'>manje</th>\r\n" + //
      "<th class=\"tip\" title='točno'>točno</th>\r\n" + //
      "<th class=\"tip\" title='više'>više</th>\r\n" + //
      "<th class=\"tip\" title='m./t.'>m./t.</th>\r\n" + //
      "<th class=\"tip\" title='v./t.'>v./t.</th>\r\n" + //
      "<th class=\"tip\">daje</th>\r\n" + //
      "<th class=\"tip\">X2</th>\r\n" + //
      "<th class=\"tip\">12</th>\r\n";

  public static void main(String[] args) {
    Document jsoup = Jsoup.parse(html);
    Elements headings = jsoup.select("th.tip");
    for (Element element : headings) {
      System.out.println(element.text());
    }
  }
}

看,这有多简单?


是的,但我有一个非常大的HTML页面需要解析并使用正则表达式作为我的第一个提示。但是这个工具看起来非常好。我会试一试。 - vale4674

0

试试这个:

Pattern pattern = Pattern.compile("<th[^>]*>(.*?)\\s*</th>");

尝试过了,但对我没用。stuken.yuri的正则表达式有效。无论如何还是谢谢。 - vale4674

0

试试这个:

Pattern pattern = Pattern.compile("<th class=\"tip\"[^>]*>(.*)</th>");

哇哦 :D 这个对我有用。谢谢。使用匹配直到“>”的好主意。 - vale4674

0

真是让人困惑,再尝试一次Pattern答案,这次加上向前和向后查找:

Pattern pattern = Pattern.compile("(?<=<th .{0,100}>).*(?=</th>)");

编辑 1
关于我尝试过,但在任何情况下都不起作用:也许你的测试环境与我的不同:

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

public class Foo1 {
   private static final String FOO_TXT = "Foo1.txt";

   public static void main(String[] args) {
      Pattern pattern = Pattern.compile("(?<=<th .{0,100}>).*(?=</th>)");

      Scanner scan = new Scanner(Foo1.class.getResourceAsStream(FOO_TXT));
      while (scan.hasNextLine()) {
         String line = scan.nextLine();
         System.out.println("Line: " + line);
         Matcher match = pattern.matcher(line);
         if (match.find()) {
            System.out.println("Match: " + match.group());
         } else {
            System.out.println("No match found");
         }
      }
   }
}

这假设文本文件名为Foo1.txt,并且它与类文件位于同一位置。


奇怪...你的模式在我的机器上真的不起作用,而其他的却可以。(我刚刚删除了我的评论,说它不起作用。我的测试框架不同,但我不知道它对匹配有什么影响...) - toto2
如果我将你的前瞻匹配部分"(?<=")更改为一个简单的非匹配组标记"(?:"),它就可以工作了。 - toto2
@toto:也许如果你编辑一下原始帖子,并向我们展示你的测试工具,最好是一个小的可编译和可运行的程序,那么我就可以更好地看到为什么我的正则表达式在你这里失败了。 - Hovercraft Full Of Eels
我把我的代码放在了答案里(不幸的是)。我现在得走了,但今晚我会检查一下是否有任何意见。我正在Windows 7上运行Java 7(beta)版本。 - toto2

0
我包含我的测试代码,因为似乎当他人拥有负/正匹配时,我却有正/负匹配。
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;

public class Regex {

public static void test(String patternString) {
    System.out.println("Test with pattern: " + patternString);
    Pattern pattern = Pattern.compile(patternString);
    String[] testStrings = {"<th class=\"tip\" title='manje'>manje</th>", "<th class=\"tip\">daje</th>"};
    for (String testString : testStrings) {
        System.out.println("> Test on " + testString);
        Matcher matcher = pattern.matcher(testString);
        if (matcher.matches()) {
            System.out.println(">> number of matches in group = " + matcher.groupCount());
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println(">>group " + i + " is " + matcher.group(i));
            }
        } else {
            System.out.println(">> no match");
        }
    }
    System.out.println("");
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    test("<th class=\"tip\"[\\s*|[.]{0,20}]>(.*?)\\s*</th>"); // op
    test("<th[^>]*>(.*?)\\s*</th>"); // Billy Moon
    test("<th class=\"tip\"[^>]*>(.*)</th>"); // stuken.yuri
    test("(?<=<th .{0,100}>).*(?=</th>)"); // Hovercraft full of Eels
    test("(?:<th .{0,100}>).*(?:</th>)");
}
}

我的输出是我得到了Billy Moon和stuken.yuri的匹配,但没有匹配OP或Hovercraft。我很想知道其他人是否也有同样的结果。我正在使用带有Windows 7的Java 7 beta。


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