Look-ahead 和 Look-behind 概念如何支持 Ruby 正则表达式中的零宽度断言概念?

2023-11-27

我刚刚经历过这个概念Zero-Width Assertions从文档中。我的脑海中浮现出一些简单的问题——

  • 为什么这样的名字Zero-Width Assertions?
  • How the Look-ahead and look-behind概念支持这样的Zero-Width Assertions概念?
  • 什么这样的?<=s,<!s,=s,<=s- 图案内有 4 个符号指示?你能帮助我集中精力了解到底发生了什么吗

我还尝试了一些小代码来理解逻辑,但对这些代码的输出不太有信心:

irb(main):001:0> "foresight".sub(/(?!s)ight/, 'ee')
=> "foresee"
irb(main):002:0> "foresight".sub(/(?=s)ight/, 'ee')
=> "foresight"
irb(main):003:0> "foresight".sub(/(?<=s)ight/, 'ee')
=> "foresee"
irb(main):004:0> "foresight".sub(/(?<!s)ight/, 'ee')
=> "foresight"

有人可以帮我理解吗?

EDIT

在这里,我尝试了两个片段,其中一个具有“零宽度断言”概念,如下所示:

irb(main):002:0> "foresight".sub(/(?!s)ight/, 'ee')
=> "foresee"

另一个没有“零宽度断言”概念,如下所示:

irb(main):003:0> "foresight".sub(/ight/, 'ee')
=> "foresee"

上面两者都产生相同的输出,现在在内部如何两者regexp他们自己移动以产生输出——你能帮我想象一下吗?

Thanks


正则表达式从左到右匹配,并沿字符串移动某种“光标”。如果您的正则表达式包含常规字符,例如a,这意味着:“如果有一封信a在光标前面,将光标向前移动一个字符,然后继续。否则,就有问题了;备份并尝试其他事情。”所以你可能会这么说a其“宽度”为一个字符。

“零宽度断言”就是这样:它asserts有关字符串的某些内容(即,如果某些条件不成立,则不匹配),但它不会向前移动光标,因为它的“宽度”为零。

您可能已经熟悉一些更简单的零宽度断言,例如^ and $。它们匹配字符串的开头和结尾。如果光标在看到这些符号时不在开头或结尾,则正则表达式引擎将失败、备份并尝试其他操作。但它们实际上并没有向前移动光标,因为它们不匹配字符;他们只检查光标在哪里。

Lookahead 和 Lookbehind 的工作方式相同。当正则表达式引擎尝试匹配它们时,它会检查around光标以查看正确的模式是否位于其前面或后面,但如果匹配,则不会移动光标。

考虑:

/(?=foo)foo/.match 'foo'

这会匹配!正则表达式引擎是这样的:

  1. 从字符串的开头开始:|foo.
  2. 正则表达式的第一部分是(?=foo)。这意味着:仅匹配如果foo出现在光标后面。可以?嗯,是的,所以我们可以继续。但光标不动,因为这是零宽度。我们还有|foo.
  3. Next is f。有没有一个f在光标前面?是的,所以继续,并将光标移过f: f|oo.
  4. Next is o。有没有一个o在光标前面?是的,所以继续,并将光标移过o: fo|o.
  5. 同样的事情又把我们带到了foo|.
  6. 我们到达了正则表达式的末尾,没有任何失败,因此模式匹配。

特别是关于您的四个主张:

  • (?=...)是“前瞻”;它断言... does出现在光标后面。

    1.9.3p125 :002 > 'jump june'.gsub(/ju(?=m)/, 'slu')
     => "slump june" 
    

    “jump”中的“ju”匹配,因为接下来是“m”。但“june”中的“ju”后面没有“m”,所以就不用管它了。

    由于它不会移动光标,因此在其后面放置任何内容时必须小心。(?=a)b永远不会匹配任何内容,因为它检查下一个字符是a, then also检查是否same性格是b,这是不可能的。

  • (?<=...)是“后视”;它断言... does appear before光标。

    1.9.3p125 :002 > 'four flour'.gsub(/(?<=f)our/, 'ive')
     => "five flour" 
    

    “four”中的“our”匹配,因为它前面有一个“f”,但“flour”中的“our”前面有一个“l”,所以它不匹配。

    就像上面一样,你必须小心你所放的东西before it. a(?<=b)永远不会匹配,因为它检查下一个字符是a,移动光标,然后检查前一个字符是否为b.

  • (?!...)是“负前瞻”;它断言... does not出现在光标后面。

    1.9.3p125 :003 > 'child children'.gsub(/child(?!ren)/, 'kid')
     => "kid children"
    

    “child”匹配,因为接下来是一个空格,而不是“ren”。 “孩子”则不然。

    这可能是我最常用的一个;精细地控制接下来不能发生的事情会派上用场。

  • (?<!...)是“负向后看”;它断言... does not appear before光标。

    1.9.3p125 :004 > 'foot root'.gsub(/(?<!r)oot/, 'eet')
     => "feet root" 
    

    “foot”中的“oot”很好,因为它前面没有“r”。 “root”中的“oot”显然有一个“r”。

    作为附加限制,大多数正则表达式引擎要求...在这种情况下具有固定长度。所以你不能使用?, +, *, or {n,m}.

你也可以嵌套它们,或者做各种疯狂的事情。我使用它们主要是为了一次性使用,我知道我永远不需要维护,所以我手头没有任何现实世界应用程序的好例子;老实说,它们很奇怪,您应该首先尝试以其他方式做您想做的事情。 :)


事后思考:语法来自Perl正则表达式,其中使用了(?后面跟着许多扩展语法的各种符号,因为?其本身无效。所以<=本身并没有任何意义;(?<=是一个完整的标记,意思是“这是回顾的开始”。就像怎样+= and ++是单独的运算符,即使它们都以+.

不过,它们很容易记住:=表示向前看(或者实际上是“这里”),<表示向后看,并且!有其传统含义“不”。


关于你后面的例子:

irb(main):002:0> "foresight".sub(/(?!s)ight/, 'ee')
=> "foresee"

irb(main):003:0> "foresight".sub(/ight/, 'ee')
=> "foresee"

是的,它们产生相同的输出。这是使用前瞻的棘手之处:

  1. 正则表达式引擎尝试了一些方法,但没有成功,现在处于fores|ight.
  2. 它检查(?!s)。是人物after光标s?不,它是i!所以该部分匹配并且匹配继续,但是光标不动,我们还有fores|ight.
  3. 它检查ight. Does ight来到光标之后?嗯,是的,所以移动光标:foresight|.
  4. 我们完成了!

光标移到子字符串上ight,这就是完整的匹配,这就是被替换的内容。

Doing (?!a)b没用,因为你说:下一个字符must not be a,和它must be b。但这与仅匹配相同b!

这有时很有用,但您需要更复杂的模式:例如,(?!3)\d将匹配任何不是 3 的数字。

这就是你想要的:

1.9.3p125 :001 > "foresight".sub(/(?<!s)ight/, 'ee')
 => "foresight" 

这断言s不来before ight.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Look-ahead 和 Look-behind 概念如何支持 Ruby 正则表达式中的零宽度断言概念? 的相关文章

  • git 匹配多个单词的标签

    我们可以得到最后一个 git 标签 它以一个单词 例如 TEST 开头 如下所示 git describe tag dirty match TEST 我想知道如何获得最后一个以 word1 开头的标签orword2 例如测试OR跑步 我尝试
  • 从正则表达式对象中提取允许字符串的最大长度

    一旦加载到 C 中 是否可以从正则表达式模式中提取允许的字符串的最大长度Regex object 如果我有一个正则表达式字符串定义为 A Z0 9 0 20 我可以使用字符串操作来获取最大允许长度20 但是 有没有一种方法可以更轻松地实现这
  • 红宝石接球和效率

    catch在 Ruby 中意味着跳出深度嵌套的代码 在 Java 中 例如用Java也可以达到同样的效果try catch用于处理异常 但它被认为是糟糕的解决方案 而且效率非常低 在 Ruby 中 我们有处理异常的方法begin raise
  • Ruby/Rails 集合到集合

    我有两个表与一个连接表连接 这只是伪代码 Library Book LibraryBooks 我需要做的是 如果我有一个图书馆的 id 我想获取该图书馆拥有的所有书籍所在的所有图书馆 因此 如果我有图书馆 1 图书馆 1 中有书籍 A 和
  • 如何从字符串中删除所有数字?

    我想删除字符串 0 9 中的所有数字 我写了这段有效的代码 words preg replace 0 words remove numbers words preg replace 1 words remove numbers words
  • Pure Bash 替换捕获组

    我有这个示例字符串 test string 13A6 该字符 数字可以是从 0 到 9 以及从 A 到 F 我想要这个输出 1 3 A 6 我有这个工作 result echo test string sed s g 我想在没有 sed 的
  • RegularExpressionAttribute - 如何使其客户端验证不区分大小写?

    我有一个用于客户端验证的字符串 private const String regex b d 5 s s d 5 A Z 2 d 3 s s 1 d 3 s 我在我的中使用这个字符串 RegularExpression regex Erro
  • 从 html 属性中删除单引号和双引号,并且除 href 和 src 之外的所有属性上都没有空格

    我正在尝试从 html 属性中删除单引号和双引号 这些属性是没有空格的单个单词 我写了这个有效的正则表达式 type title data toggle colspan scope role media name rel id class
  • Python 非贪婪正则表达式

    我如何制作一个像这样的Python正则表达式 这样 给定 a b c d e 蟒蛇匹配 b 代替 b c d 我知道我可以使用 代替 但我正在寻找一种更通用的解决方案 使我的正则表达式更加干净 有没有办法告诉python 嘿 尽快匹配这个
  • 扩展 RegExp 以获取文件扩展名

    我知道 已经有很多基于 RegExp 的解决方案 但是我找不到适合我需求的解决方案 我有以下函数来获取 URL 的各个部分 但我还需要文件扩展名 var getPathParts function url var m url match w
  • 使用 ruby​​ 调整动画 GIF 图像的大小?

    我正在尝试将 GIF 图像调整为不同的尺寸 我在 ruby 中使用 RMagick 库 但对于某些 gif 图像 即使我缩小 GIF 的大小 文件大小似乎也会增加 我正在以相同的纵横比调整图像图像的大小 这是我的代码 require rma
  • 我可以让这个 Ruby 代码更快并且/或使用更少的内存吗?

    我有一个Array of StringRuby 中的对象由如下单词组成 animals cat horse dog cat dog bird dog sheep chicken cow 我想将其转换为另一个Array of String对象
  • 如何在 CakePHP 中“验证”人名?

    我有一个 PHP 脚本 应该检查 有效 的人名 但最近破解了带有空格的名称 因此我们向验证器添加了空格 除了这样做之外 有没有办法向 CakePHP 的验证器添加黑名单以阻止所有 无效 字符 而不是允许 有效 字符 注意 我 通常 知道如何
  • 如何声明依赖于参数化任务的 Rake 任务?

    我见过一些任务具有参数和依赖项任务的示例 例如 task name first name last name gt pre name do t args args with defaults first name gt John last
  • 如何处理 Nokogiri 中的 404 未找到错误

    我正在使用 Nokogiri 来抓取网页 很少有 url 需要猜测 当它们不存在时 会返回 404 未找到错误 有没有办法捕获这个异常 http yoursite page 38475 gt page number 38475 doesn
  • sed 错误“未终止的 's' 命令”故障排除

    我正在构建一个script https stackoverflow com questions 4036832 replacing a specific term in an xml file其中 它将用文件夹路径替换 XML 文件中的模式
  • 在 Rails 中本地化嵌套虚拟属性

    怎么可能本地化嵌套虚拟属性在 Rails 中 该模型 class User lt ActiveRecord Base attr accessor company information This is used in callbacks e
  • 使用正则表达式搜索 Ruby 数组

    你好 我有一个小的 ruby 函数 它可以分割出一个 Ruby 数组 如下所示 def rearrange arr from to sidx arr index from eidx arr index to arr sidx arr sid
  • 在 Rails 项目中保存自定义异常定义的常规位置是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 当创建自己的自定义异常时 例如 class ThingExploded lt StandardError end class ThingIsMi
  • JavaScript 中的实时摩尔斯电码转换器

    在看到谷歌关于莫尔斯电码 gmail 的愚人节笑话后 我想我应该尝试用 javascript 创建一个实时莫尔斯电码转换器 我正在使用正则表达式和替换将莫尔斯电码更改为字符 例如 replace g a replace g r 我遇到的问题

随机推荐