【问题标题】:How can I determine the index of the same set of characters between two strings that are of different lengths?如何确定两个长度不同的字符串之间同一组字符的索引?
【发布时间】:2015-06-09 05:20:03
【问题描述】:

我先为标题道歉,我不知道如何措辞。

我正在尝试在两个不同但相似的字符串中查找相似字符或字符集的索引。

  • 字符串 A:I <color=red><b>really</b></color> don't like spiders!
  • 字符串 B:I really don't like spiders!

相关文本是相同的,但是A 有一些格式,而B 没有。我通过使用A 并运行正则表达式来查找并用空字符串替换所有<contents> 得到B

现在假设我在B 中选择了索引为9 的字符,这将是单词don't 中的字母d。然后如何在字符串A 中确定don't 中的字母d 也需要选择,它的索引为35(如果我计算正确的话)?

编辑:可能是重要信息,这些标签用于 Unity 中的富文本。几乎在所有方面都与 HTML 非常相似。

【问题讨论】:

  • 你应该检查 HtmlAgilityPack,你不应该在 html 中使用正则表达式
  • 我建议您阅读整个单词,然后选择其中的字符。否则,两个字符串都没有对称性。您可以选择单词,然后选择字符。
  • 为什么需要这样做?
  • 你绝对需要解析那个。一旦你这样做了,区分文本和格式指令(你解析的,因此是元信息)并不难。
  • 这实际上是 Unity 中一种奇怪的 BBCode 形式,类似于 HTML,但不兼容。我最初只想去除使用正则表达式非常容易的格式。虽然现在我意识到如果我想复制格式化文本,我需要在复制到剪贴板时找到两者的索引。这是关于“为什么”我需要它的冗长解释,主要是针对 Unity 非常有限的 UI 系统的解决方法。

标签: c# arrays regex string


【解决方案1】:

正如我在 cmets 中已经建议的那样,您应该为这种格式编写自己的解析器,将格式作为元数据保存在文本旁边。例如,您可以保留一个简单的字符串部分列表,其中每个部分代表具有相同格式的连续文本。

你可以从这样简单的开始:

import re

def parse (string):
    it = iter([None] + re.split('(<[^>]+>)', string))

    parsed = []
    curFormat = {}
    for fmt, text in zip(it, it):
        if fmt is None:
            curFormat = {}
        elif fmt.startswith('</'):
            fmt = fmt[2:-1]
            del curFormat[fmt]
        else:
            fmt = fmt[1:-1]
            if '=' in fmt:
                name, value = fmt.split('=', 1)
                curFormat[name] = value
            else:
                curFormat[fmt] = True

        if text != '':
            parsed.append((text, list(curFormat.items())))

    return parsed

对于您的文本,这将为您提供以下结果:

>>> text = "I <color=red><b>really</b></color> don't like spiders!"
>>> parsed = parse(text)
>>> parsed
[('I ', []), ('really', [('color', 'red'), ('b', True)]), (" don't like spiders!", [])]

如您所见,您会得到成对的文本,以及该特定文本部分的格式信息列表。如果你想获取底层文本,你可以迭代第一个列表元素:

>>> ''.join(t for t, fmt in parsed)
"I really don't like spiders!"

除此之外,您还可以创建自己的索引方法(注意,这个方法真的很粗糙):

def index (parsed, start, length):
    output = ''
    for t, fmt in parsed:
        if start < 0:
            output += t
        elif start > len(t):
            start -= len(t)
        else:
            output += t[start:]
            start = -1
        if len(output) > length:
            return output[:length]
    return output
>>> index(parsed, 4, 5)
'ally '
>>> index(parsed, 7, 6)
"y don'"

最后,你可以把这一切都放在一个自定义类型中,它实现了迭代器协议和序列协议,所以你可以像普通字符串一样使用它。

【讨论】:

  • 谢谢。我采纳了您的建议,并在相同的概念下提出了解决方案。
猜你喜欢
  • 2020-07-19
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 2018-04-20
  • 2011-11-20
  • 2015-05-04
  • 1970-01-01
  • 2021-06-18
相关资源
最近更新 更多