【问题标题】:Regex for capturing numbered text list用于捕获编号文本列表的正则表达式
【发布时间】:2010-03-21 13:41:20
【问题描述】:

我有一个测试列表,我正在尝试使用正则表达式捕获数据。

以下是文本格式示例:

(1) this is a sample string /(2) something strange /(3) another bit of text /(4) the last one/ something!/

我有一个正则表达式,目前可以正确捕捉到这一点,但我在使其在异常条件下工作时遇到了一些困难。

这是我的正则表达式

/\(?\d\d?\)([^\)]+)(\/|\z)/

不幸的是,有些数据包含这样的括号:

(1) this is a sample string (1998-1999) /(2) something strange (blah) /(3) another bit of text /(4) the last one/ something!/

子字符串 '(1998-1999)' 和 '(blah)' 让它失败了!

有人想试试这个吗? 谢谢 :D

【问题讨论】:

  • 你没有说正则表达式应该捕获什么。
  • 抱歉没有更具体。我现在正在查看大量答案(至少 2 个看起来正确)grin 我试图捕获我的示例捕获的文本(即英文文本减去编号)。

标签: regex parsing


【解决方案1】:

我会试试这个:

\((\d+)\)\s+(.*?)(?=/(?:\(\d+\)|\z))

这个看起来很吓人的正则表达式执行以下操作:

  • 它查找括在括号中的一个或多个数字并捕获它们;
  • 括号中的数字后必须至少有一个空白字符。此空白被忽略(未捕获);
  • 使用了非贪婪通配符表达式。对于此类问题,这是(恕我直言)使用否定字符组(例如[^/]+)的更好方法;
  • 正向前瞻 ((?=...)) 表示表达式后面必须跟一个反斜杠,然后是以下之一:
    • 一个或多个用括号括起来的数字;或
    • 字符串终止符。

给你一个 PHP 的例子(你没有指定你的语言):

$s = '(1) this is a sample string (1998-1999) /(2) something strange (blah) /(3) another bit of text /(4) the last one/ something!/';
preg_match_all('!\((\d+)\)\s+(.*?)(?=/(?:\(\d+\)|\z))!', $s, $matches);
print_r($matches);

输出:

Array
(
    [0] => Array
        (
            [0] => (1) this is a sample string (1998-1999) 
            [1] => (2) something strange (blah) 
            [2] => (3) another bit of text 
            [3] => (4) the last one/ something!
        )

    [1] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
        )

    [2] => Array
        (
            [0] => this is a sample string (1998-1999) 
            [1] => something strange (blah) 
            [2] => another bit of text 
            [3] => the last one/ something!
        )

)

一些注意事项:

  • 您没有指定要捕获的内容。我假设了列表项编号和文本。这可能是错误的,在这种情况下只需删除那些捕获括号。无论哪种方式,您都可以获得整场比赛;
  • 我已经从匹配中删除了尾部斜线。这可能不是你的意图。同样,只需更改捕获以适应;
  • 我允许使用任意位数的商品编号。你的版本只允许两个。如果您喜欢这种方式,请将 \d+ 替换为 \d\d?

【讨论】:

  • 这当然是劳斯莱斯的答案。它也很好地捕捉了 Ruby 中的所有内容。格式化为 Ruby 我正在使用这个 ... /(\d+).*?\/(?=(|$)/
  • Cletus:我刚刚注意到最后一个条目中嵌入的正斜杠被剪掉了。我已经投票给你了,我现在正在破译正则表达式,但你能建议如何在正斜杠后包含文本吗?谢谢
  • @crunchyt 你能解释一下吗?尾随的/,你想要它在第二个捕获的组中吗?还是你的意思是别的?
  • 嗨@cletus,字符串的最后一部分是“/(4) the last one/ something!/”,但正则表达式错过了“/ something”。在您的示例结果中,第三个数组维度是我想要捕获的,但包括嵌入正斜杠之后的任何文本。干杯
  • @crunchyt 已修复。查看新版本。
【解决方案2】:

/添加到字符串的开头,将(0)添加到字符串的末尾,然后使用\/\(\d+\)模式分割整个字符串,并丢弃第一个和最后一个空元素。

【讨论】:

    【解决方案3】:

    只要/不能出现在文本中...

     \(?\d?\d[^/]+
    

    【讨论】:

    • 这很接近,但我需要数字之间的整个字符串。
    猜你喜欢
    • 1970-01-01
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多