gpt4 book ai didi

java - 用于基于正则表达式的 XML 解析的分隔符?

转载 作者:行者123 更新时间:2023-11-30 04:58:32 26 4
gpt4 key购买 nike

首先,我非常清楚尝试手写 XML 解析器是一个糟糕的主意,并且 ZA̡͊͠͝LGΌ IS̯͈͕̹̘̱ͮ̂̂ TO͇̹̺ͅƝ̴ş̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡ H̸̡̪̯ͨ ͊̽̅̾̎ş̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜ş̴̟̟͙̞ͩ ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ等等。

也就是说,我有一个任务,我应该抓取一个网页,去掉标签(处理<p><a href>有点不同),并显示漂亮的、无标签的文本。我不允许使用 org.xml.sax 包或类似的东西。

我们类还没学过正则表达式,大部分同学都在念叨着String.indexOf()的邪恶咒语。 。对我来说,破解基于事件的 {X,HT}ML 解析器似乎更容易(更不用说更好)。

所以我有一个 Scanner对于网页流,并具有以下内容(为简洁起见,删除了一些细节):

stream.useDelimiter("\r?\n|\r"); // Use platform-independent newlines
//as delimiter
// 1 2 3 4 5 6 7 8 9 10
String tagRE = "([^<>]*?)(<!?\\s*)(/?)(\\s*)(\\w*)(\\s*[^<>]*?)(/?)(\\s*)(>)([^<>]*)";
//(Reluctant-anything) < whitespace optional-/ whitespace (word) whitespace
//reluctant-anything > (greedy-anything)

fireOpenFileEvent();
Pattern tagPat = Pattern.compile(tagRE);
while(stream.hasNextLine())
{
if(stream.hasNext(tagPat))
{
String toParse = stream.next(tagPat);
Matcher m = tagPat.matcher(toParse);
if(! m.matches()) System.err.println("Impossible non-match!");

fireTextEvent(m.group(1));
String tag = m.group(5);
if(! m.group(7).equals("")) //Self-closing tag
{
fireTagEvent(new XMLElement(tag, false));
fireTagEvent(new XMLElement(tag, true));
}
else
{
fireTagEvent(new XMLElement(tag, m.group(3).equals("/")));
}
fireTextEvent(m.group(10));
}
else //No tags (regex doesn't match). Just plain text
{
fireTextEvent(stream.nextLine);
}
}
fireEOFEvent();

这在许多情况下都非常有效,除了一种情况——当一行上有多个标签时。我真的希望Scanner不会将事物分解为 token - 并且调用 next(pattern)为了匹配,会根据需要消耗掉尽可能多的流。因此,如果一行是 <b>Hello World!</b> ,它将匹配 <b>Hello World!在一次迭代中,然后 </b>下一次。相反,它一次处理一行。由于整行与模式不匹配,因此它由 else 子句处理。并且没有标签被剥离。

那么最好的方法是什么?我可以使用某种神奇的分隔符吗?我应该让正则表达式匹配任何带有标签的内容,砍掉第一个标签,然后递归处理字符串的其余部分吗?我应该尝试一个巨大的 hack,并将每个“<”替换为“\n<”吗?我是不是一般都走错了路?

提前致谢。

最佳答案

当您调用 next(Pattern) 方法时,您已经告诉扫描器下一个标记是下一个分隔符之前的所有内容;唯一的问题是, token 与模式匹配吗?这与其他 nextXXX() 方法一致(例如,如果下一个标记看起来不像 int,则 nextInt() 会失败),但是每个人都期望 next(Pattern) 以不同的方式工作。

我认为您正在寻找的方法是 findWithinHorizo​​n();它忽略分隔符并只查找下一个匹配项,与 Matcher 的 find() 方法相同。试试这个:扔掉所有 hasNextLine()hasNext(Pattern) 东西并使用这个框架:

String lastHit = stream.findWithinHorizon(tagRE, 0);  // always use '0'
while (lastHit != null)
{
MatchResult lastMatch = stream.match();

// ...

lastHit = stream.findWithinHorizon(tagRE, 0);
}

填写事件触发代码,根据需要调整正则表达式,但不要使用 Scanner 的任何其他方法(除了打开和关闭流之外)。当您尝试做任何复杂的事情时,大多数 Scanner 的 API 似乎都会妨碍您。

扫描仪的 API 可能臃肿且不直观,但它有一个非常有用的功能:以这种方式使用,它将继续从流中读取,不仅直到找到匹配项,而且直到确定不再有 可以从相同的起始位置进行匹配。换句话说,它的工作方式就像 Matcher 的 find() 方法处理静态字符串一样。在我所知道的所有其他正则表达式风格中,只有 Boost提供类似的东西。

关于java - 用于基于正则表达式的 XML 解析的分隔符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7698640/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com