【问题标题】:RegexKitLite: Match Expression --> Match anything except ] --> Match ]RegexKitLite: 匹配表达式 --> 匹配除 ] --> 匹配]
【发布时间】:2010-12-03 18:53:00
【问题描述】:

我实际上是在尝试替换大文本中的所有脚注。我在 Objective-C 中这样做有多种原因,所以请假设这个约束。

每个脚注都有这个:[脚注

每个脚注都以这个结尾:]

这两个标记之间绝对可以有任何内容,包括换行符。但是,它们之间永远不会有 ]。

所以,基本上我想匹配 [脚注,然后匹配除 ] 之外的任何内容,直到匹配 ]。

这是我能找到的最接近所有脚注的方法:

NSString *regexString = @"[\\[][F][o][o][t][n][o][t][e][^\\]\n]*[\\]]";

使用这个正则表达式可以识别 780/889 脚注。似乎这 780 个都不是误报。它似乎唯一遗漏的是那些有换行符的脚注。

我在 www.regular-expressions.info 上花费了很长时间,特别是在关于点的页面上 (http://www.regular-expressions.info/dot.html)。这帮助我创建了上述正则表达式,但我还没有真正弄清楚如何包含任何字符或换行符,除了右括号。

改用以下正则表达式可以捕获所有脚注,但它捕获的文本太多,因为 * 是贪婪的:(?s)[\\[][F][o][o][t][n][o][t][e].*[\\]]

下面是一些运行正则表达式的示例文本:

  <p id="id00082">[Footnote 1: In the history of Florence in the early part of the XVIth century <i>Piero di Braccio Martelli</i> is frequently mentioned as <i>Commissario della Signoria</i>. He was famous for his learning and at his death left four books on Mathematics ready for the press; comp. LITTA, <i>Famiglie celebri Italiane</i>, <i>Famiglia Martelli di Firenze</i>.—In the Official Catalogue of MSS. in the Brit. Mus., New Series Vol. I., where this passage is printed, <i>Barto</i> has been wrongly given for Braccio.</p>

  <p id="id00083">2. <i>addi 22 di marzo 1508</i>. The Christian era was computed in Florence at that time from the Incarnation (Lady day, March 25th). Hence this should be 1509 by our reckoning.</p>

  <p id="id00084">3. <i>racolto tratto di molte carte le quali io ho qui copiate</i>. We must suppose that Leonardo means that he has copied out his own MSS. and not those of others. The first thirteen leaves of the MS. in the Brit. Mus. are a fair copy of some notes on physics.]</p>

  <p id="id00085">Suggestions for the arrangement of MSS treating of particular subjects.(5-8).</p>

When you put together the science of the motions of water, remember to include under each proposition its application and use, in order that this science may not be useless.--

[Footnote 2: A comparatively small portion of Leonardo's notes on water-power was published at Bologna in 1828, under the title: "_Del moto e misura dell'Acqua, di L. da Vinci_".]

在此示例中,有两个脚注和一些非脚注文本。如您所见,第一个脚注在其中包含两个换行符。第二个不包含换行符。

我上面提到的第一个正则表达式将设法捕获此示例文本中的脚注 2,但它不会捕获脚注 1,因为它包含换行符。

对我的正则表达式的任何改进将不胜感激。

【问题讨论】:

    标签: objective-c regex regexkitlite


    【解决方案1】:

    试试

    @"\\[Footnote[^\\]]*\\]";
    

    这应该匹配换行符。也不需要将单个字符放入字符类中。

    作为注释,多行正则表达式(没有字符串转义):

    \[        # match a literal [
    Footnote  # match literal "Footnote"
    [^\]]*    # match zero or more characters except ]
    \]        # match ]
    

    在字符类 ([...]) 中,插入符号 ^ 具有不同的含义;它否定了类的内容。所以[ab] 匹配ab,而[^ab] 匹配除ab 之外的任何字符。

    当然,如果您有嵌套的脚注,这将出现故障。 [Footnote foo [footnote bar] foo] 之类的文本将从开头匹配到 bar]。为避免这种情况,请将正则表达式更改为

    @"\\[Footnote[^\\]\\[]*\\]";
    

    所以既不允许打开也不允许关闭括号。然后,当然,您只匹配最里面的脚注,并且必须将相同的正则表达式应用两次(或更多,取决于最大嵌套级别)到整个文本,逐层“剥离”。

    【讨论】:

    • 这似乎有效。它匹配 883 次,但它替换了所有脚注(889),因此显然有 6 次它包含两个脚注而不是一个。也许有三个嵌套的脚注?我需要一段时间才能找到它们。为什么这行得通?我不明白 [^\]]* 是如何工作的。这不应该只是寻找以右括号开头的行吗?我认为 ^ 字符应该“在行首匹配”。
    • 太棒了!谢谢!你的解释很有道理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 2014-01-07
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多