为什么perl正则表达式不像我需要的那样贪婪?

时间:2015-12-07 21:50:56

标签: regex string perl regex-greedy perl5

所以出现这个字符串:

!NAME: "Slot 10 SubSlot 0"

最终引号后可能会有一些东西,但这与手头的任务无关。

目标是,我希望在Slot UP UNTIL最终引号后捕获所有内容。

我已经为这项任务尝试了两个正则表达式

/^!NAME:\s+\".*(Slot[\w|\s|\d+]+)\"/;

另一个:

/^!NAME:\s+\".*(Slot.+)\"/;

但这些只捕捉

Slot 0

Slot之后可能会有很大的不同。它可能是这样的:

'Slot 4' (this works, but the capture string will not always be this small)

'Slot 4 Subslot 12 Internal Subslot 14 External'

'Slot 75 Internal Slot 12 External'

我们唯一确定的是,我们想要的部分将以' Slot'开头,并以引号结束。中间的任何其他东西都在空中。

我所展示的内容有什么问题?特别是第二个,因为我认为'。'操作员贪婪并尽可能多地捕获?

此脚本的目的是捕获要在另一个程序中解析的这些详细信息。

5 个答案:

答案 0 :(得分:2)

贪婪。

TextView

由于您的目标字符串在两个位置匹配/^!NAME:\s+\".*(Slot[\w|\s|\d+]+)\"/; ^^ |----- The greedy part is here. ,因此引用后的Slot \d+会使第一个字符串黯然失色。尝试使表达的那部分非贪婪:

.*

答案 1 :(得分:1)

这应该捕获所有不是Slot之后但引用之前的引用的内容:

/^!NAME:\s+\"Slot([^\"]*)\"/

如果因某种原因需要,请包含Slot部分

/^!NAME:\s+\"(Slot[^\"]*)\"/

答案 2 :(得分:1)

最安全的答案:

Glide.with(context)
            .load(Gallery_Constants.IMAGES)
            .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .into(viewHolder.mImage);

您还可以确保/^ !NAME: \s* " (?:(?!Slot).)* Slot ( [^"]* ) "/x 不属于另一个词:

Slot

诀窍是知道/^ !NAME: \s* " (?:(?!Slot).)* \b Slot \b ( [^"]* ) "/x (?:(?!STRING).)*STRING[^CHAR]*

答案 3 :(得分:0)

这适用于您的所有示例文本:

^!NAME:\s*"(Slot.*?)"

https://regex101.com/r/hB1cT3/2

注意:除了“Slot”文本之外,你的所有示例都不包含任何引号,那么为什么你在.*作为引号中的第一个内容?正如上面提到的暴民,这就是造成问题的原因。我在这里删除了它。

答案 4 :(得分:0)

这是一个简单的解决方案:

/(Slot[^"]+)/

这是在行动:

my $s = '!NAME: "Slot 10 SubSlot 0"';
$s =~ /(Slot[^"]+)/;
print $1;

# Slot 10 SubSlot 0

如果您需要指定该行以!NAME:开头,那么只需将其展开为:

/^!NAME:\s"(Slot[^"]+)/