【问题标题】:How the Anchor \z and \G works in Ruby?Anchor \z 和 \G 如何在 Ruby 中工作?
【发布时间】:2012-12-31 05:14:10
【问题描述】:

我正在使用 Ruby1.9.3。我是这个平台的新手。

doc我刚刚熟悉了两个anchor,它们是\z\G。现在我用\z 玩了一下,看看它是如何工作的,因为定义(EndEnd of String)让我感到困惑,我无法理解它是什么意思是说-End。所以我尝试了下面的小sn-ps。但还是抓不住。

代码

irb(main):011:0> str = "Hit him on the head me 2\n" + "Hit him on the head wit>
=> "Hit him on the head me 2\nHit him on the head with a 24\n"
irb(main):012:0> str =~ /\d\z/
=> nil

irb(main):013:0> str = "Hit him on the head me 24 2\n" + "Hit him on the head >
=> "Hit him on the head me 24 2\nHit him on the head with a 24\n"
irb(main):014:0> str =~ /\d\z/
=> nil

irb(main):018:0> str = "Hit1 him on the head me 24 2\n" + "Hit him on the head>
=> "Hit1 him on the head me 24 2\nHit him on the head with a11 11 24\n"
irb(main):019:0> str =~ /\d\z/
=> nil
irb(main):020:0>

每次我得到nil 作为输出。那么\z 的计算是如何进行的呢? End 是什么意思? - 我认为我的概念与文档中的End 字有任何问题。所以任何人都可以帮助我了解发生的原因以及为什么会发生这种情况?

而且我也没有找到锚\G 的任何示例。请你们提供任何示例来可视化\G 在实时编程中的使用方式?

编辑

irb(main):029:0>
irb(main):030:0*  ("{123}{45}{6789}").scan(/\G(?!^)\{\d+\}/)
=> []
irb(main):031:0>  ('{123}{45}{6789}').scan(/\G(?!^)\{\d+\}/)
=> []
irb(main):032:0>

谢谢

【问题讨论】:

  • 你想匹配什么模式?
  • 我正在寻找一个代码来可视化如何使用\G 的样子以及它在模式匹配中的工作原理?
  • 您不应将答案中的代码包含在您的问题中。新读者可能会认为这是您的代码(并尝试帮助您),这会让他们感到困惑。我已经用一个经过测试的工作示例更新了我的答案。
  • @Cyborgx37 感谢您指导我正确的方向! +1你的评论!

标签: ruby regex ruby-1.9.3


【解决方案1】:

\z 匹配输入的结尾。您正在尝试查找输入末尾出现 4 的匹配项。问题是,输入末尾有一个换行符,所以你找不到匹配项。 \Z 匹配输入的末尾或输入末尾的换行符。

所以:

/\d\z/

匹配中的“4”:

"24"

和:

/\d\Z/

匹配上例中的“4”和以下示例中的“4”:

"24\n"

查看这个问题,例如使用\G:
Examples of regex matcher \G (The end of the previous match) in Java would be nice


更新:\G 的实际用途

我想出了一个更真实的例子。假设您有一个由无法很好预测的任意字符分隔的单词列表(或者列出的可能性太多)。您想匹配这些单词,其中每个单词都是其自己的匹配项,直到某个特定单词,之后您不想再匹配任何单词。例如:

foo,bar.baz:buz'fuzz*hoo-har/haz|fil^bil!bak

您希望匹配每个单词直到 'har'。您不想匹配 'har' 或后面的任何单词。您可以使用以下模式相对轻松地做到这一点:

/(?<=^|\G\W)\w+\b(?<!har)/

rubular

第一次尝试将匹配输入的开头,然后是零个非单词字符,然后是 3 个单词字符 ('foo'),然后是单词边界。最后,否定的lookbehind确保刚刚匹配的单词不是'har'。

在第二次尝试时,匹配会在最后一场比赛结束时重新开始。匹配了 1 个非单词字符(',' - 尽管由于后视而未捕获,这是一个零宽度断言),然后是 3 个字符('bar')。

这会一直持续到匹配 'har' 为止,此时会触发负向回溯并且匹配失败。因为所有匹配项都应该“附加”到最后一个成功匹配项,所以不会匹配其他单词。

结果是:

foo
bar
baz
buz
fuzz
hoo

如果您想反转它并在“har”之后包含所有单词(但同样不包括“har”),您可以使用如下表达式:

/(?!^)(?<=har\W|\G\W)\w+\b/

rubular

这将匹配一个以 'har' 开头的单词或最后一个匹配的结尾(除非我们必须确保不匹配输入的开头)。匹配列表是:

haz
fil
bil
bak

如果你确实想匹配 'har' 和所有以下单词,你可以使用这个:

/\bhar\b|(?!^)(?<=\G\W)\w+\b/

rubular

这会产生以下匹配项:

har
haz
fil
bil
bak

【讨论】:

  • 没有正确理解您的观点。你能拿走我粘贴的任何代码以及我为什么失败并在那里调整自己以显示什么可以使它成功吗?
  • 我想要Ruby 喜欢\G 的代码。我不是 Java 语法的上帝!
  • +1给你解释,但真的很想看到\G的小红宝石代码
  • 老实说,我从来没有遇到过需要 \G 的场景。您通常可以更直观地使用另一个构造。如果您不熟悉正则表达式,我不会担心学习它...请注意它存在,以防您在某人的代码中遇到它,但不要担心提出必须使用它的场景。跨度>
  • @RubyTheBang - 我用一个可能的例子更新了我的答案。
【解决方案2】:

听起来您想知道 Regex 的工作原理吗?或者您想知道 Regex 如何与 ruby​​ 配合使用?

看看这些。

Regexp Class description

The Regex Coach - 非常适合测试正则表达式匹配

Regex cheat sheet

我理解 \G 是一个边界匹配字符。所以它会告诉下一场比赛在最后一场比赛结束时开始。也许因为你还没有进行匹配,所以你不能有第二个。

Here 是我能找到的最好的例子。它不是红宝石,但概念应该是相同的。

我收回this 可能更有用

【讨论】:

  • 我想要 Regex 和 Ruby 1.9.3
  • +1 供您参考!
  • 您的声明中包含一些代码将不胜感激!这将帮助我快速理解这个概念!
猜你喜欢
  • 2018-04-12
  • 2019-11-13
  • 2022-11-17
  • 2018-10-26
  • 2013-04-28
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 2012-06-26
相关资源
最近更新 更多