如果字符串列表不在内,则在两个字符串之间获取字符串

时间:2012-04-11 01:07:16

标签: c# regex linq

希望标题不会太混乱。

我有一个包含故事的文件目录。我需要得到两个句子之间的字符串列表(总是向前),只要它们之间的字符串不包含另一个列表中包含的任何句子。每个故事。

所以,例如,我有一个名单"大狗","她跟着他",安妮咬她的嘴唇"等等。

然后我有一个文件,这可能是一个包含谁知道什么的故事。而且我想找到"之间的字符串;他跳过她"和#34;她吻了他"但只有当它们之间的字符串不包含第一个列表中的任何句子或它们本身时。

我已经找到了一些方法可以做到这一点,但大多数都是如此慢,需要差不多一个小时才能完成一个文件,我相信必须有更好更快的方法来做到这一点。注意我没有在这里添加它,因为我不想限制我正在做的事情的解决方案,这可能不是最好的方法。

1 个答案:

答案 0 :(得分:1)

不确定您使用的算法是什么来解决您描述的问题,但这就是我在这种情况下会做的事情

<强>前处理:

  • 确保任何空白字符序列减少为一个(空格,制表符等)。
  • 将整个文本设为小写或大写。

<强>过程:

  • 将所有标记的单词预加载到内存中(有序列表使用二进制搜索,理论上此过程应该只在第一次创建列表时消耗时间,继续对条目进行排序并以稍后加载的格式保留这些条目在任何进一步的添加应该进行二进制搜索,以确定该单词是否在列表中,并将该条目放在相应的位置/插槽中。
  • 将所有捕获短语预加载到内存中(这里我们可以使用与加载单词相同的方法)。
  • 穿过文件并保留与标记列表匹配的任何单词的偏移量/位置和长度。为了考虑大文件,偏移量应该很长。
  • 查找标记词的序列。在第一个单词之后的任何匹配是序列的候选,因为我们删除所有空白字符序列,如果该单词的偏移量等于前一个单词的偏移量加上前一个单词,则我们确定WordN是序列的一部分。 length加1,这里的1表示分隔两个单词的空白字符。 word2Offset = word1Offset + word1Length + 1。
  • 检查找到的任何序列匹配是否开始或匹配捕获短语。

实施资产:

  • Word:一个简单的String就足以代表这些单词了。所有单词必须以小写或大写形式存储。
  • 组件:组件是一个结构,用于保存文件中文字的偏移量
  • 词组:是两个或更多组件的组合,一个简单的列表就足够了。
  • 当时读取一个字符的文件有助于快速确定单词和单词序列。例如,每个空格意味着一个新的组件被读取,基本上是一个单词,所以如果匹配与否,我们可以使用检查,如果它匹配并且是第一个匹配,我们不知道它是否是一个序列,但是一旦我们读到第二个或第三个字,我们知道是否匹配我们可以检查当前偏移是否遵循我们之前描述的规则。

检查阶段

  • 如果没有标记的单词,则不会匹配任何短语。几乎不可能,但谁知道。
  • 文件中的任何单词匹配序列代表短语检查的候选者。
  • 检查单词长度和后来的单词内容,以检查短语和候选人之间的匹配。在这里,您可以检查部分或整个短语是否匹配。

在两个序列阶段之间获取文本。

由于阶段只是一个组件列表,我们只需要从第一个短语的最后一个单词的偏移量和长度之和到第二个短语的第一个单词的偏移量读取文件。

From = PhaseALastWordOffset + PhaseALastWordLength
To = PhaseBFirstWordOffset
Contents = StoryFile.readSegment(From,To);

希望它有所帮助。