gpt4 book ai didi

ruby - 如何使用正则表达式交换 ruby​​ 字符串中的数字位置?

转载 作者:数据小太阳 更新时间:2023-10-29 08:17:14 25 4
gpt4 key购买 nike

假设我有一个字符串"2foo9 8bar5"。我需要交换包装每个单词的两个数字。结果应如下所示 "9foo2 5bar8"

我可以用下面的代码来完成。

def swap_num(str)
str = str.gsub(/(\d)(\D+)(\d)/, '\3\2\1')
end

但是如果我有这样的字符串 "2foo9 8bar5 3+=_1",这个 swap_num 方法将交换最后一部分的数字 "3 +=_1" 也不是我想要的。我只想交换包含 WORDS 的数字,而不是任何 CHARACTERS。

我尝试了以下方法,但没有成功。

def swap_num(str)
str = str.gsub(/(\d)([a-zA-Z]+)(\d)/, '\3\2\1')
end

有什么方法可以用简单的正则表达式来实现吗?谢谢!

更新:

对不起各位。我犯了一个错误,str = str.gsub(/(\d)([a-zA-Z]+)(\d)/, '\3\2\1') 确实有效我的目的。但是如果我像这样使用双引号 "\3\2\1" 就不会起作用了。

谢谢,@Robin 指出我的原始代码确实有效。还要感谢@Cary Swoveland 和@Andie2302 为我提供了 2 个新的解决方案!真的很感激!

最佳答案

你可以这样做:

R = /
\b # match a word boundary
(\d+) # match ?= 1 digits, capture in group #1
([a-z]+) # match >= 1 lower case letters, capture in group #2
(\d+) # match >= 1 digits, capture in group #3
\b # match a word boundary
/ix # case indifferent (/i) and extended mode (/x)

def flip_numbers(str)
str.gsub(R) { $3+$2+$1 }
end

flip_numbers("2foo9 8bar5")
#=> "9foo2 5bar8"
flip_numbers("233foo91 8bar5")
#=> "91foo233 5bar8"
flip_numbers("2foo9 8bar5 3+=_1")
#=> "9foo2 5bar8 3+=_1"
flip_numbers("a2foo9 8bar5 3bat7c")
#=> "a2foo9 5bar8 3bat7c"

请注意,在最后一个示例中,由于单词边界的要求,a2foo93bat7c 中的数字不会交换。

每个匹配的字符串都传递给 gsub 的 block ,该 block 计算该字符串的替换。我们可以将 block 写成:

{ |s| <code here> }

其中 block 变量等于匹配的字符串。在第一个示例中:

s = "2foo9"

我们希望将其替换为:

"9foo2"

三个捕获组的内容包含在全局变量中:

$1 #=> "9"
$2 #=> "foo"
$3 #=> "2"

因此替换字符串是:

$3+$2+$1 #=> "2foo9".

因此 block 被写成:

{ |s| $3+$2+$1 }

但由于我们在此计算中不使用 block 变量 s,因此我们可以从 block 中省略 |s|。这是一种很好的做法,因为它减少了出错的可能性,并且还告诉读者未使用 block 变量。

表达式 $3+$2+$1 可以作为 gsub 的参数,但在那种情况下必须写成:

"2foo9 8bar5".gsub(R, '\3\2\1')
#=> "9foo2 5bar8"

"2foo9 8bar5".gsub(R, "\\3\\2\\1")
#=> "9foo2 5bar8"

这里的选择纯粹是风格上的。

关于ruby - 如何使用正则表达式交换 ruby​​ 字符串中的数字位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28120882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com