- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我非常清楚尝试手写 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)
以不同的方式工作。
我认为您正在寻找的方法是 findWithinHorizon()
;它忽略分隔符并只查找下一个匹配项,与 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/
我有一个加号/减号按钮,希望用户不能选择超过 20 个但不知道如何让它工作。我尝试使用 min="1"max="5 属性,但它们不起作用。这是我的代码和一个 fiddle 链接。https://jsf
我正在尝试复制顶部底部图,如示例 here但它没有正确渲染(紫色系列有 +ve 和 -ve 值,绿色为负值)留下杂乱的人工制品。我也在努力创建一个玩具示例来复制这个问题,所以我希望尽管我缺乏数据,但有
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 6 年前。 社区去年审查了是
这个问题在这里已经有了答案: Adding two positive integers gives negative answer.Why? (4 个答案) 关闭 5 年前。 我遇到了一个奇怪的问题
有谁知道如何将字符串值类型 -4,5 或 5,4 转换为 double -4.5 或 5.4? 最佳答案 只需使用 Double.parseDouble(Locale, String); 糟糕,我很困
我正在尝试根据 TextBlob 分类插入一个仅包含“正”或“负”字符串的新数据框列:对于我的 df 的第一行,结果是 ( pos , 0.75, 0.2499999999999997)我想要' 正
我对 VBA 非常陌生,无法理解如何在一个循环中完成 2 个任务。我非常感谢您的帮助。 我已经能够根据第 3 列中的数据更改第 2 列中的数值,但我不明白如何将负值的字体更改为红色。 表格的大小每月都
欢迎, 我正在使用 jquery 通过 POST 发送表单。 这就是我获得值(value)的方式。 var mytext = $("#textareaid").val(); var dataStrin
double d = 0; // random decimal value with it's integral part within the range of Int32 and always p
我有这个字符串: var a='abc123#xyz123'; 我想构建 2 个正则表达式替换函数: 1) 用 '*' 替换所有确实有 future '#'的字符(不包括'#') 所以结果应该是这样的
我正在使用 DialogFragment。当用户从 Gmail 平板电脑应用程序的屏幕与下面示例图片中的编辑文本进行交互时,我希望正面和负面按钮保持在键盘上方。 在我的尝试中不起作用,这是我的 Dia
从组装艺术一书中,我复制了这句话: In the two’s complement system, the H.O. bit of a number is a sign bit. If the H.O
是否有更好更优雅的方法来实现下面的简单代码(diffYear、A 和 B 是数字): diffYear = yearA - yearB; if (diffYear == 0) { A = B
我正在设计一种语言,并尝试确定 true 应该是 0x01 还是 0xFF。显然,所有非零值都将转换为 true,但我正在尝试确定确切的内部表示。 每种选择的优点和缺点是什么? 最佳答案 没关系,只要
在我的 dialogfragment 类的 OnCreateDialog 中,我正在这样做: AlertDialog.Builder builder = new AlertDialog.Builder
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda usin
我偶然发现了一个奇怪的 NSDecimalNumber 行为:对于某些值,调用 integerValue、longValue、longLongValue 等,返回意想不到的值(value)。示例: l
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda using
我有这个正则表达式来测试用户输入是否有效: value.length === 0 || value === '-' || (!isNaN(parseFloat(value)) && /^-?\d+\.
我想用高斯混合模型拟合数据集,数据集包含大约 120k 个样本,每个样本有大约 130 个维度。当我使用 matlab 执行此操作时,我运行脚本(簇号为 1000): gm = fitgmdist(d
我是一名优秀的程序员,十分优秀!