【问题标题】:extract word with regular expression用正则表达式提取单词
【发布时间】:2010-06-07 18:35:21
【问题描述】:

我有一个字符串1/temperatoA,2/CelcieusB!23/33/44,55/66/77,我想提取单词temperatoACelcieusB

我有这个正则表达式(\d+/(\w+),?)*!,但我只得到匹配1/temperatoA,2/CelcieusB!

为什么?

【问题讨论】:

  • 您使用的是哪个正则表达式引擎?
  • 您需要接受答案。

标签: regex perl pcre


【解决方案1】:

您的整个匹配结果为'1/temperatoA,2/CelcieusB',因为它匹配以下表达式:

qr{ (       # begin group 
      \d+   # at least one digit
      /     # followed by a slash
     (\w+)  # followed by at least one word characters
     ,?     # maybe a comma
    )*      # ANY number of repetitions of this pattern.
}x;

'1/temperatoA,' 首先完成捕获#1,但是由于您要求引擎尽可能多地捕获这些,它会返回并发现该模式在'2/CelcieusB' 中重复(逗号不是必需的)。所以整场比赛就是你所说的那样,但你可能没想到的是'2/CelcieusB' 替换 '1/temperatoA,'$1,所以@987654328 @读取'2/CelcieusB'

任何时候您想在特定字符串中捕获符合特定模式的任何内容,最好使用 global 标志并将捕获分配到一个数组中。由于数组不是像$1 这样的单个标量,它可以保存为捕获#1 捕获的所有值。

当我这样做时:

my $str   = '1/temperatoA,2/CelcieusB!23/33/44,55/66/77';
my $regex = qr{(\d+/(\w+))};
if ( my @matches = $str =~ /$regex/g ) { 
    print Dumper( \@matches );
}

我明白了:

$VAR1 = [
          '1/temperatoA',
          'temperatoA',
          '2/CelcieusB',
          'CelcieusB',
          '23/33',
          '33',
          '55/66',
          '66'
        ];

现在,我认为这可能不是您所期望的。但是'3''6'单词字符,所以——在斜线之后——它们符合表达式。

因此,如果这是一个问题,您可以将您的正则表达式更改为等效的:qr{(\d+/(\p{Alpha}\w*))},指定第一个字符必须是 alpha 后跟任意数量的单词字符。然后转储看起来像这样:

$VAR1 = [
          '1/temperatoA',
          'temperatoA',
          '2/CelcieusB',
          'CelcieusB'
        ];

如果您只需要'temperatoA''CelcieusB',那么您捕获的内容超出了您的需要,并且您希望您的正则表达式为qr{\d+/(\p{Alpha}\w*)}

但是,在捕获表达式中捕获多个块的秘诀是将匹配项分配给一个数组,然后您可以对数组进行排序以查看它是否包含您想要的数据。

【讨论】:

  • +1 这对我来说似乎是一个非常好的解释 - 超出了职责范围。
【解决方案2】:

这里的问题是:为什么要使用明显错误的正则表达式?你是怎么得到的?

你想要的表达式如下:

(\w+)

【讨论】:

  • 我使用正则表达式,我只想要 tempatoA 和 CelcieusB vor !
  • @farka:向我们展示如何您正在使用该表达式。错误的不是表达方式,而是你使用它的方式。
  • 我只想提取单词 bevor !和之间 1/word1 2/word2 3/word21...n/word
【解决方案3】:

使用兼容 Perl 的正则表达式引擎,您可以搜索

(?<=\d/)\w+(?=.*!)

(?&lt;=\d/) 断言比赛开始前有一个数字和一个斜线

\w+ 匹配标识符。这允许使用字母、数字和下划线。如果您只想允许字母,请改用[A-Za-z]+

(?=.*!) 断言字符串前面有一个! - i。 e.一旦我们通过了!,正则表达式就会失败。

根据您使用的语言,您可能需要转义正则表达式中的某些字符。

E. g.,为了在 C 中使用(使用 PCRE 库),您需要转义反斜杠:

myregexp = pcre_compile("(?<=\\d/)\\w+(?=.*!)", 0, &error, &erroroffset, NULL);

【讨论】:

  • 我使用 pcrl perl comapatibe 正则表达式
  • 使用哪种编程语言? PCRE 可用于许多不同的语言。好消息是正则表达式可以工作,因为 PCRE 支持环视。
  • 请回答我的问题 - 否则无法帮助您。
【解决方案4】:

这行得通吗?

/([[:alpha:]]\w+)\b(?=.*!)

我做了以下假设...

  1. 单词以字母字符开头。
  2. 单词总是紧跟在斜线后面。中间没有空格,中间没有单词。
  3. 感叹号后的单词将被忽略。
  4. 您有某种循环来捕获多个单词。我对 C 库不够熟悉,无法举个例子。

[[:alpha:]] 匹配任何字母字符。

\b 匹配单词边界。

(?=.*!) 来自Tim Pietzcker's post

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 2019-12-31
    • 2021-10-30
    • 1970-01-01
    • 2021-12-24
    • 2014-06-30
    相关资源
    最近更新 更多