转换前后的字符串索引

时间:2012-03-26 15:21:12

标签: java regex string

在Java中,我有一个任意HTML文档作为字符串。为简单起见,请说:

String original = "Hello, <strong>this</strong> is a string";

我记录了字符串中的各个位置,始终在文本中,而不是在标记内。例如,单词“is”的开头和结尾的索引是29和31。

然后我对字符串执行转换 - 在这种情况下剥离HTML标记。这留下了:

original = "Hello, this is a string";

是否有一种优雅的方式来获取单词“is”的新开始和结束索引(12和14)?

我能想到的一个可能的解决方案是在每个原始索引处插入“标志”,剥离HTML,然后在记录其位置时删除标记。这不应该导致HTML剥离的任何问题,因为索引总是出现在标记之外。

如果这实际上是最好的方式,那么有没有人对任何HTML文档中肯定不会出现的“旗帜”选择有任何建议?

4 个答案:

答案 0 :(得分:1)

当您删除每个标记时,您显然知道刚删除的标记的长度。对于每个此类标记,请查找以后的所有字索引值,而不是刚刚删除的标记的索引。对于任何找到的,从索引中减去标记的长度。这样可以在删除标记时使索引保持同步,从而使任务比在最后计算调整时简单得多。

答案 1 :(得分:1)

最好的方法取决于您如何剥离HTML标记。如果您只是删除&lt;&gt;中包含的所有内容括号,然后您可以循环遍历旧字符串并保持&lt;&gt;之外的所有内容的计数旧索引前面的括号。沿着这些方向的东西可能会起作用:

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;
}

答案 2 :(得分:1)

不是真的。主要问题是String是最终的(因此您无法扩展该类)并且大多数地方使用StringCharSequence就足够了(事实上你可以创建自己的实现。)

所以你有两个选择:

  1. 创建自己的HTML剥离代码
  2. 剥离HTML标记后重新索引文档
  3. 如果您只需要剥离HTML,那么您可以使用此正则表达式:<[^>]+>除非您拥有CDATA blocks(您可以通过查找<![CDATA[进行检查),否则此保证会有效。或内联JavaScript(查找没有<script>属性的src代码。)

答案 3 :(得分:0)

我创建了一个npm软件包- Potsiu!-解决了这个问题。

波头!在转换后的字符串上找到索引,其周围环境使用levenshtein距离最匹配原始字符串中原始索引的环境。

您可以在此处查看:Potsiu!