捕获组不';使用Ruby扫描方法无法正常工作

捕获组不';使用Ruby扫描方法无法正常工作,ruby,regex,Ruby,Regex,我需要从多行字符串中获取一个浮点数组(正数和负数)。例如:-45.124、1124.325等 我是这样做的: text.scan(/(\+|\-)?\d+(\.\d+)?/) 虽然它可以很好地工作(捕获组0匹配我需要的所有内容),但它在Ruby代码中不起作用 你知道为什么会发生这种情况,以及我如何改进吗?请参阅: 如果模式不包含组,则每个单独的结果都由匹配的字符串$&组成。如果模式包含组,则每个单独的结果本身就是一个数组,每个组包含一个条目 您应该删除捕获组(如果它们是冗余的),或者创建它们(

我需要从多行字符串中获取一个浮点数组(正数和负数)。例如:
-45.124、1124.325等

我是这样做的:

text.scan(/(\+|\-)?\d+(\.\d+)?/)
虽然它可以很好地工作(捕获组0匹配我需要的所有内容),但它在Ruby代码中不起作用

你知道为什么会发生这种情况,以及我如何改进吗?

请参阅:

如果模式不包含组,则每个单独的结果都由匹配的字符串
$&
组成。如果模式包含组,则每个单独的结果本身就是一个数组,每个组包含一个条目

您应该删除捕获组(如果它们是冗余的),或者创建它们(如果您只需要对一系列模式进行分组,以便能够量化它们),或者在无法避免捕获组的情况下使用额外的代码/组。

  • 在此场景中,捕获组用于量化模式序列,因此您只需通过将所有未捕获的
    替换为
    (?:
    )将捕获组转换为非捕获组即可(此处仅出现一次):
  • text=“-45.1241124.325”
    放置文本。扫描(/[+-]?\d+(?:\。\d+)/)
    
    见,输出:

    -45.124
    1124.325
    
    好的,如果您还需要匹配浮动,如
    .04
    ,您可以使用
    [+-]?\d*\.\d+
    。请参阅

  • 在某些情况下,您无法摆脱捕获组,例如,正则表达式包含对捕获组的反向引用。在这种情况下,您可以a)声明一个变量来存储所有匹配项,并在
    扫描
    块中收集所有匹配项,或者b)使用另一个捕获组将整个模式括起来,并映射结果以从每个匹配中获取第一项,c)您可以使用a和regex作为单个参数返回枚举数,使用
    。要获取匹配数组,请执行以下操作:
  • text=“1123456678”
    #备选案文a:
    结果=[]
    text.scan(/(\d)\1+/){results[“11”,“666666”]
    #备选案文b:
    p text.scan(/((\d)\2+/).map(&:first)#=>[“11”,“666666”]
    #备选案文c:
    p text.gsub(/(\d)\1+/)。to_a#=>[“11”,“666666”]
    

    假设小数点前有一个前导数字


    请参见

    如果您需要复杂模式匹配的捕获组,但希望通过
    返回整个表达式。扫描
    ,这对您很有用

    假设您希望从带有html图像标记的标记文本中获取此字符串中的图像URL:

    str=%(
    之前
    之后
    ).脱衣舞
    
    您可以定义一个正则表达式来匹配URL,还可以使用一个正则表达式来构建/测试您的
    Regexp

    image\u regex=
    /https\:\/\/(用户-)图像。(githubusercontent | zenhubusercontent.com.*\b/
    
    现在,您不需要每个子捕获组,只需要在
    .scan
    中包含整个表达式,您只需将整个模式包装在捕获组中,并按如下方式使用它:

    image\u regex=
    /(https\:\/\/(用户-)图像。(githubusercontent | zenhubusercontent.com.*\b)/
    str.scan(image_regex).map(&:first)
    => ["https://user-images.githubusercontent.com/1949900/75255445-f59fb800-57af-11ea-9b7a-e075f55bf150.png",
    "https://user-images.githubusercontent.com/1949900/75255473-02bca700-57b0-11ea-852a-58424698cfb0.png"]
    
    这实际上是如何工作的? 由于您有3个捕获组,
    .scan
    单独将返回一个
    数组
    ,每个捕获一个:

    str.scan(image\u regex)
    => [["https://user-images.githubusercontent.com/111222333/75255445-f59fb800-57af-11ea-9b7a-e075f55bf150.png“,”用户-“,”githubusercontent“],
    ["https://images.zenhubusercontent.com/11223344e051aa2c30577d9d17/110459e6-915b-47cd-9d2c-0714c8f76f68,无,“zenhubusercontent”]]
    

    由于我们只需要第一个(outter)捕获组,我们可以直接调用
    .map(&:first)

    另一个很棒的网站是@onebree,谢谢你的链接!我肯定会用它来创建ruby Regexest,这让我大开眼界。感谢你的案例2另一个选择是
    “11234566666678”。gsub(/(\d)\1+/)。to#a#=>[“11”,“666666”]
    @caryswovel越多越好。虽然问题是关于
    .scan
    ,但实现同样效果的其他方法也很受欢迎。这个正则表达式有一个缺点:它也匹配
    4.
    。@Stribizev发现得很好。更新了否,现在它不匹配
    1
    ([+-]?\d+\.\d+)