Java 在由特殊标记标记的字符串中查找节的位置

Java 在由特殊标记标记的字符串中查找节的位置,java,string,algorithm,oop,data-structures,Java,String,Algorithm,Oop,Data Structures,我有一个字符串要处理,它的一部分用自定义标记“标记”,以指示字符串中与其余部分“不同”的区域 示例: 这是一个{TypeAStart}任意长的{TypeAEnd}文本 任意长部分是字符串中感兴趣的区域。 我想要一个好方法来获取字符串这一部分的开始和结束索引,使用regex我可以做到这一点() 使用这种方法的问题是: 1) 我不能轻易概括它 2) 我的主要目标是以字符串结束,这是一个任意长文本,并具有另一个数据结构,描述应用了哪个标记以及在最终字符串中的位置。 我看不到任何通过正则表达式直接实现这

我有一个字符串要处理,它的一部分用自定义标记“标记”,以指示字符串中与其余部分“不同”的区域

示例:
这是一个{TypeAStart}任意长的{TypeAEnd}文本

任意长
部分是字符串中感兴趣的区域。
我想要一个好方法来获取字符串这一部分的开始和结束索引,使用regex我可以做到这一点()
使用这种方法的问题是:
1) 我不能轻易概括它
2) 我的主要目标是以字符串
结束,这是一个任意长文本
,并具有另一个数据结构,描述应用了哪个标记以及在最终字符串中的位置。
我看不到任何通过正则表达式直接实现这一点的方法

我希望实现的是,例如,将这些自定义标记作为成对的数组,并处理字符串以查找所有这些子字符串。
输入示例:

This is an {TypeAStart}arbitrary long {SomeOtherStart} very very very {SomeOtherEnd} long long{TypeAEnd} text  
已知标记:
[TypeAStart,TypeAEnd],[SomeOtherStart,SomeOtherEnd]等

输出:

  • 这是一个任意的很长很长的文本
  • TypeA[11,50],其他[26,40]

如何实现这一点?

我有一个开源项目,可以帮助实现这一点:

假设您有一个枚举标记,其值为TYPEASTART和TYPEAEND,并假设这些值实现了一个方法String text(),该方法获取要搜索的字符串

您可以将标记的模式添加到DfaBuilder,这将为您提供一个DFA,您可以使用它来查找字符串中的标记,如下所示:

DfaBuilder<Marker> builder = new DfaBuilder<>();
for (Marker val : Marker.values())
{
    builder.addPattern(Pattern.match(val.text()), val);
}
DfaState<Marker> START_STATE = builder.build();
如果记住开始标记的位置,则在找到匹配的结束标记时,可以轻松提取标记之间的字符串


要在没有标记的情况下获取字符串,请打开一个StringBuilder并在其中填充标记之间的内容,直到结束

,这样基本上就是复制XML语法,只需使用
{somethingEnd}
而不是
?如果是这样的话,我担心我的方法是用正则表达式将它们替换为XML标记,然后通过XML解析器运行结果:)@JiriTousek:它实际上没有那么高级或复杂。文本很小,标记很少,嵌套不频繁,只有2-3个标记。我可以硬编码任何东西,但那样的编码会使代码过于复杂和不可维护。基本上是一团糟,我正试图avoid@JiiTousek:另外,XML解析器有何帮助?我希望索引不是实际的文本我可以想象使用SAX解析器然后捕获事件:文本-添加到输出StringBuilder,标记开始-记住它的位置基于StringBuilder的实际大小,标记结束-获取位置,与标记开始配对并存储结果。您也可以用与原始格式类似的方式执行此操作,但你需要自己解析它。如果输入很短,并且文本中除了标记之外不允许有
{
}
,则不太难。基本上,您只需要一个输出StringBuilder和一堆打开的标记。
StringMatcher matcher = new StringMatcher(someString);
Marker found;
while((found = matcher.findNext(START_STATE))!=null)
{
    //found is the kind of marker we found
    //this is the start position in the string
    int startPos = matcher.getLastMatchStart();
    //this is the end position in the string
    int endPos = matcher.getLastMatchEnd();
}