Java 转换前后的字符串索引
在Java中,我有一个任意的HTML文档作为字符串。为简单起见,请说:Java 转换前后的字符串索引,java,regex,string,Java,Regex,String,在Java中,我有一个任意的HTML文档作为字符串。为简单起见,请说: String original = "Hello, <strong>this</strong> is a string"; 现在(12和14)是否有一种优雅的方式来获取单词“Is”的新开始和结束索引 我能想到的一个可能的解决方案是在每个原始索引处插入一个“标志”,剥离HTML,然后在记录其位置时删除标志。这不会导致HTML剥离出现任何问题,因为索引总是出现在标记之外 如果这实际上是最好的方法,那么有
String original = "Hello, <strong>this</strong> is a string";
现在(12和14)是否有一种优雅的方式来获取单词“Is”的新开始和结束索引
我能想到的一个可能的解决方案是在每个原始索引处插入一个“标志”,剥离HTML,然后在记录其位置时删除标志。这不会导致HTML剥离出现任何问题,因为索引总是出现在标记之外
如果这实际上是最好的方法,那么有没有人对任何HTML文档中都不会出现的“flag”有什么好的选择建议?当您去掉每个标记时,您显然知道刚刚删除的标记的长度。对于每一个这样的标记,查找所有比刚刚删除的标记的索引更晚的单词索引值。对于找到的任何标记,从索引中减去标记的长度。这会在删除标记时保持索引同步,使任务比最后计算调整要简单得多 最佳方法取决于如何剥离HTML标记。如果只是删除括号中的所有内容,那么只需循环使用旧字符串,并在旧索引之前保留括号外的所有内容的计数。沿着这些思路的一些东西可能会起作用:
public String newIndex(String str, int oldIndex) {
int newIndex = 0;
boolean inBracket = false;
for (int i = 0; i < str.length(); i++) {
if (i == oldIndex) return newIndex;
char c = str.charAt(i);
if (c == '<') inBracket = true;
else if (c == '>') inBracket = false;
else if (!inBracket) newIndex++;
}
return newIndex;
}
publicstringnewindex(stringstr,intoldinex){
int newIndex=0;
布尔内布拉克=假;
对于(int i=0;i
不太可能。主要的问题是String
是final(因此您不能扩展类),并且在大多数使用String
的地方,一个CharSequence
就足够了(实际上您可以创建自己的实现)
所以你有两个选择:
如果您只需要剥离HTML,那么您可以使用这个regexp:
]+>
这保证可以工作,除非您有(您可以通过查找)或内联JavaScript(查找没有src
属性的
标记)。我已经创建了一个npm包-Potsiu-解决这个问题
波绍!使用levenshtein距离在转换的字符串上查找环境与原始字符串中原始索引的环境最匹配的索引
你可以在这里查看:任何你不能说的原因:startNew=starteld-(lengthNew-lengthOld)?@mfrankli我想我对我的示例过于简化了一点-实际上,在所需索引之后可能会出现其他html标记,当删除这些标记时,这将防止我将字符串长度的变化与从字符串开始的距离的变化等同起来。很好。一个缺点是我不能再使用像JSoup这样的东西来删除HTML,我必须通过正则表达式自己来完成。另外,我觉得这不会那么有效,但这对我来说不是一个大问题。你最初是如何获得单词索引的?你能不能在拆下标签后简单地收集它们?你是对的,那里的效率不是很好,但是除非你有一个巨大的HTML源代码或大量的这样的页面要处理,否则这种差异可能不会伤害用户。谢谢你的例子。理想情况下,我希望使用JSoup之类的工具来剥离HTML,因为它包括空白规范化和HTML实体解码,但这绝对是一种可能性。正如在另一个答案中提到的,如果您将其折叠到删除HTML标记的过程中,您将获得更好的性能。但是手工操作是出了名的困难,你肯定会遇到意想不到的情况。如果您手头有一个库,可以为您去除标记,并且可以从中索引输出,那么我绝对推荐这种方法。
public String newIndex(String str, int oldIndex) {
int newIndex = 0;
boolean inBracket = false;
for (int i = 0; i < str.length(); i++) {
if (i == oldIndex) return newIndex;
char c = str.charAt(i);
if (c == '<') inBracket = true;
else if (c == '>') inBracket = false;
else if (!inBracket) newIndex++;
}
return newIndex;
}