0

所以看起来这个问题已经被问到几乎所有的语言都在阳光下......除了C ++。我有一个 XML 文档,其中有一些 bbcode 存储在文本节点中。我正在寻找删除它的最佳方法,我想我会在这里查看是否有人知道一些预先构建的库或一些自己完成此操作的有效方法。我正在考虑可能删除介于“[”和“]”字符之间的任何内容,但是使用提供给我的 XML 文档会变得很疯狂,因为 BB 的许多实例都在表单中'[[blahblahblah]]',有些'[blahblahblah].'

这是 XML 文档。标签之间的所有数据<text>都被添加到一个字符串中,有什么建议吗?

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.7/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.7/ http://www.mediawiki.org/xml/export-0.7.xsd" version="0.7" xml:lang="en">
 <page>
   <title>Human Anatomy/Osteology/Axialskeleton</title>
   <ns>0</ns>
   <id>181313</id>
   <revision>
      <id>1481605</id>
      <parentid>1379871</parentid>
      <timestamp>2009-04-26T02:03:12Z</timestamp>
      <contributor>
          <username>Adrignola</username>
          <id>169232</id>
      </contributor>
      <minor />
      <comment>+Category</comment>
      <sha1>hvxozde19haz4yhwj73ez82tf2bocbz</sha1>
      <text xml:space="preserve"> [[Image:Axial_skeleton_diagram.svg|thumb|240px|right|Diagram of the axial skeleton]]

       The Axial Skeleton is a division of the human skeleton and is named because it makes up the longitudinal ''axis'' of the body. It consists of the skull, hyoid bone, vertebral column, sternum and ribs. It is widely accepted to be made up of 80 bones, although this number varies from individual to individual.

       [[Category:{{FULLBOOKNAME}}|{{FULLCHAPTERNAME}}]]</text>
   </revision>
  </page>
  <page>
    <title>Horn/General/Fingering Chart</title>
    <ns>0</ns>
    <id>23346</id>
    <revision>
        <id>1942387</id>
        <parentid>1734837</parentid>
        <timestamp>2010-10-02T20:21:09Z</timestamp>
        <contributor>
            <username>Nat682</username>
            <id>144010</id>
        </contributor>
        <comment>added important note</comment>
        <sha1>lana7m8m9r23oor0nh24ky45v71sai9</sha1>
        <text xml:space="preserve">{{HornNavGeneral}}
     The horn spans four plus octaves depending on the player and uses both the treble and bass clefs. In this chart it is assumed the player is using a double-horn with F and Bb sides. The number 1 indicates that the index-finger valve should be depressed, the number 2 indicates that the middle-finger valve should be depressed and the number 3 indicates that the ring-finger valve should be depressed. There are eight possible valve combinations among the first, second and third valves: 0, 1, 2, 3, 1-2, 1-3, 2-3, and 1-2-3. However, there are effectively seven combinations, because 1-2 will produce the same notes, perhaps slightly out of tune, as 3 alone. One depresses the thumb key to use the Bb side of the horn.
    [[Image:Fingering chart.png]]
    [[Category:Horn]]</text>
    </revision>
  </page>
</mediawiki>

因此,如果您查看每个标签的底部<page>,您会看到类似[[Category:{{FULLBOOKNAME}}|{{FULLCHAPTERNAME}}]]的内容,这就是我想要删除的内容。

4

1 回答 1

2

我假设数据是以您可以读取的迭代器的形式提供给您的。如果您以 a 的形式获得它,那么std::string获得一个可以读取的迭代器非常容易。

在这种情况下,你想要的是一个提升filter_iterator: http: //www.boost.org/doc/libs/1_39_0/libs/iterator/doc/filter_iterator.html

您想要的过滤器功能非常简单。您跟踪[您看到的数量并减去]您看到的数量(停止在 0)。当你的计数是正数时,你过滤掉了这个角色。

如果您不能使用boost,但您是从 获得它std::string,那么这有点棘手。但只有一点。 std::copy_if作品。

如果您使用的是 C++11,那么 lambda 会让这变得非常简单。如果没有,您将不得不编写自己的算数[s 的函子。

作为一个简单案例的具体示例:您正在接受 astd::string并且想要生成 astd::string没有任何[]分隔的内容。

struct SquareBracketStripper
{
  enum { open_bracket = '[', close_bracket = ']' };
  size_t count;
  SquareBracketStripper():count(0) {}
  bool operator()(char c)
  {
    bool skip = (count > 0) || c == open_bracket;
    if (c == open_bracket) {
      ++count;
    } else if (c== close_bracket && count > 0) {
      --count;
    }
    return skip;
  }
};

std::string FilterBBCode( std::string input ) {
  input.erase(input.end(), std::remove_if( input.begin(), input.end(), SquareBracketStripper() ) );
  return input;
}

它处理嵌套[]s 的任意深度。

帮助您永远不必将filter_iterator整个字符串加载到内存中,如果您不知道输入的格式错误,这很有用。[]当您可以流式传输数据并即时进行过滤时,不需要将几 TB 的数据从磁盘加载到内存中以进行过滤。但是您的用例可能并不在乎。

于 2012-11-24T03:49:00.097 回答