【问题标题】:Parse strings of certain patterns: Extract multiple phrases from one phrase解析特定模式的字符串:从一个短语中提取多个短语
【发布时间】:2019-12-02 04:25:28
【问题描述】:

所以从这个模式的一个短语:You can't make omelet(te)s(or an omelet(te)) without breaking eggs,我需要提取四个短语:
You can't make omelets without breaking eggs
You can't make omelettes without breaking eggs
You can't make an omelet without breaking eggs
You can't make an omelette without breaking eggs

这是否可能只使用Regex,或者如果不能,如何在编程语言中实现?

提前致谢。

【问题讨论】:

  • 正则表达式是你想要使用的相反方向的东西。也就是说,You can't make (?:omlets|omlettes|an omlet|an omelette) without breaking eggs 模式是您用来匹配四个变体中的任何一个的。
  • 是的,我想提取比匹配更难。 :)
  • 有一个名为Xeger的Java库可以做这种事情。
  • Xegger 看起来很有趣。我会调查一下。谢谢推荐。
  • 这不是该页面的副本;此外,该问题的解决方案在这里甚至不起作用,因为这里没有正则表达式可供测试。

标签: regex perl parsing


【解决方案1】:

也许是的,可以使用类似于以下的表达式:

You can't make (?:an)?\s*\b(?:omelett?e?s?)\b\swithout breaking eggs

表达式在regex101.com 的右上方面板中进行了解释,如果您想探索/简化/修改它,在this link 中,您可以查看它如何与一些示例输入进行匹配,如果您愿意的话。

测试

use strict;
use warnings;

my $str = 'You can\'t make omelets without breaking eggs';
my $regex = qr/^You can't make (?:an)?\s*\b(?:omelett?e?s?)\b\swithout breaking eggs$/p;

if ( $str =~ /$regex/g ) {
  print "${^MATCH}";
}

【讨论】:

  • 这不能回答问题,单独的正则表达式无法提取您的模式使用的各种组合。请重新阅读问题。
【解决方案2】:

使用更新的代码进行编辑。 行之后的原始消息。

这里是多个或的更新代码,但再次使用括号和管道方法。

#!/usr/bin/perl

my $string = "You can't make (omelet(te)s)|(an omelet(te))|(the omlet(te))|(scrambbled egg(s)) without breaking eggs";
my @count = $string=~m/\|/g;
my $x = scalar @count;
my $a= '\\|(\\(.+\\))';
my $search='(\\(.+\\))';
## Build your search string
for (my $i=1;$i<=$x;$i++) {
  $search.=$a;
}
$search.=$end;
my @c = $string=~m/$search/gm;

##  Create another string to destroy and reconstruct later. ($stripped)
my $stripped = $string;
$stripped=~s/^(.*?)(\(.+\)\|\(.+\))((.*?$)|($))/$1$3/;
foreach(@c) {

#remove parenthesis
  $_=~s/^\((.+)\)$/$1/;
  $pattern1 = $_;
## Recontruct $stripped to original
  $stripped = $string;
##  Strip enclosed item out of string
  $_=~s/\(.+\)//;
##  Insert manipulated string into $stripped
  $stripped=~s/^(.*?)(\(.+\)\|\(.+\))((.*?$)|($))/$1$_$3/;
  print "$stripped\n";
##  Pattern 1 Strip enclosed item out of string
  $pattern1=~s/\((.+)\)/$1/;
## Recontruct $stripped to original
  $stripped = $string;
##  Insert manipulated string into $stripped
  $stripped=~s/^(.*?)(\(.+\)\|\(.+\))((.*?$)|($))/$1$pattern1$3/;
  print "$stripped\n";

}

这应该涵盖多个选项。

下面的原始消息:

也许如果你稍微重构一下这个短语,它会更容易。就像将选项放在括号和分隔符中一样,这样会更容易。如果语法选项不是一个选项,那么忽略我的建议:-)

示例短语: 不打破鸡蛋就无法制作 (omelet(te)s)|(an omelet(te))

#!/usr/bin/perl
my $string = "You can't make (omelet(te)s)|(an omelet(te)) without breaking eggs";
my @c = $string=~m/(\(.+\))\|(\(.+\))/gm;

##  Create another string to destroy and reconstruct later. ($stripped)
my $stripped = $string;
$stripped=~s/^(.*?)(\(.+\)\|\(.+\))((.*?$)|($))/$1$3/;

foreach(@c) {
#remove parenthesis
  $_=~s/^\((.+)\)$/$1/;
  $pattern1 = $_;
## Recontruct $stripped to original
  $stripped = $string;
##  Strip enclosed item out of string
  $_=~s/\(.+\)//;
##  Insert manipulated string into $stripped
  $stripped=~s/^(.*?)(\(.+\)\|\(.+\))((.*?$)|($))/$1$_$3/;
  print "$stripped\n";
##  Pattern 1 Strip enclosed item out of string
  $pattern1=~s/\((.+)\)/$1/;
##  Recontruct $stripped to original
  $stripped = $string;
##  Insert manipulated string into $stripped
  $stripped=~s/^(.*?)(\(.+\)\|\(.+\))((.*?$)|($))/$1$pattern1$3/;
print "$stripped\n";

}

如果你想更深入,你可以在外括号内添加多个括起来的括号来替换和循环它,就像在初始字符串 @c 上使用 did 一样。

【讨论】:

  • 感谢您的回答。 @hashtagjet 不过,You can't make omelet(te)s(or an omelet(te)) without breaking eggs 是许多类似模式的例子之一。即一个短语中可能有多个(or…)
  • 我将对多个 or 进行编辑,但使用该 ()|() 方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2019-05-19
相关资源
最近更新 更多