捕获组不';使用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+)