如何在ruby中合并连续的GSUB

如何在ruby中合并连续的GSUB,ruby,regex,gsub,Ruby,Regex,Gsub,我有以下几点 address.gsub(/^\d*/, "").gsub(/\d*-?\d*$/, "").gsub(/\# ?\d*/,"") 这可以在一个gsub中完成吗?我想传递一个模式列表,而不是一个模式——它们都被相同的东西所取代 您可以将它们与交替运算符(|)组合使用: 您可能需要添加更多的空白清理。您可能需要切换到以下选项之一: /\A\d*|\d*-?\d*\z|\# ?\d*/ /\A\d*|\d*-?\d*\Z|\# ?\d*/ 取决于数据的真实外观以及处理换行符的方式。

我有以下几点

address.gsub(/^\d*/, "").gsub(/\d*-?\d*$/, "").gsub(/\# ?\d*/,"")

这可以在一个gsub中完成吗?我想传递一个模式列表,而不是一个模式——它们都被相同的东西所取代

您可以将它们与交替运算符(
|
)组合使用:

您可能需要添加更多的空白清理。您可能需要切换到以下选项之一:

/\A\d*|\d*-?\d*\z|\# ?\d*/
/\A\d*|\d*-?\d*\Z|\# ?\d*/

取决于数据的真实外观以及处理换行符的方式。

组合正则表达式是一个好主意,而且相对简单,但我想推荐一些额外的更改。也就是说:

address.gsub(/^\d+|\d+(?:-\d+)?$|\# *\d+/, "")
在原始正则表达式中,
^\d*
\d*-?\d*$
将始终匹配,因为它们不必使用任何字符。因此,您保证在每一行上执行两次替换,即使这只是用空字符串替换空字符串。在我的正则表达式中,
^\d+
不需要进行匹配,除非行首至少有一个数字,
\d+(?:-\d+)$
匹配行尾看起来像整数或范围表达式的内容

您的第三个正则表达式,
\\\\\?\d*
将匹配任何
字符,如果
后面跟一个空格和一些数字,它也会接受这些字符。根据您的其他正则表达式和我处理其他问题的经验判断,我怀疑您是想匹配
#
的,前提是后面跟一个或多个数字,中间有可选空格。我的第三个正则表达式就是这么做的

如果我的任何猜测是错误的,请描述一下你试图做什么,我会尽我所能想出正确的正则表达式。但我真的不认为前两个正则表达式至少是你想要的


编辑(回答评论):在使用正则表达式时,您应该始终注意不匹配的正则表达式和不匹配的正则表达式之间的区别。你说你把正则表达式应用于街道地址。如果地址不是以门牌号开头,
^\d*
将不匹配任何内容,也就是说,它将报告成功匹配,所述匹配由地址中第一个字符前面的空字符串组成

这对您来说并不重要,您只是用另一个空字符串替换它。但是为什么要费心去做替换呢?如果将正则表达式更改为
^\d+
,它将报告失败的匹配,并且不会执行任何替换。无论哪种方式,结果都是相同的,但是“匹配注释”场景(
^\d*
)会导致大量额外的工作,而“不匹配”场景可以避免这些工作。在高通量情况下,这可能是一个救命稻草


另外两个正则表达式带来了额外的复杂性:
\d*-?\d*$
可以匹配字符串末尾的连字符(例如
“123-”
,甚至
“-”
);和
\\\35;?\ d*
可以匹配字符串中任意位置的哈希符号,而不仅仅是公寓/办公室号码的一部分。你知道你的数据,所以你可能知道这些问题都不会出现;我只是想让你知道他们。我的正则表达式
\d+(?:-\d+)$
处理尾随连字符问题,并且
\\\*\d+
至少确保哈希符号后面有数字。

我认为如果将它们组合在一个gsub()正则表达式中,作为替代,
它会更改起始搜索位置的上下文

例如,这些行中的每一行都从上一个
正则表达式替换。
s/^\d*//g

s/\d*-?\d*$//g

s/\\\?\d*//g

而这个
s/^\d*\d*-?\d*$\\\\\\\\d*//g

继续搜索/替换上次匹配结束的位置,可能会产生不同的总体输出,特别是因为许多子表达式搜索类似的
如果不是相同的字符,则仅通过线锚来区分

我认为在这种情况下,您的正则表达式足够独特,当然也改变了顺序

更改结果。

完全符合我的要求。数据中没有换行符。使用\A和\Z而不是^and$是否更好?他们俩work@sanon:取决于您希望如何处理嵌入的换行符。基本上,
^
$
匹配行的开头和结尾,但
\A
\z
(或
\z
)匹配整个字符串的开头和结尾
^
$
都可以。如果备选方案的数量有点大,您可能需要使用。我正在尝试删除地址中的所有内容,除了街道名称、城市和州。我从前面取下任何号码,但停在一个空白处,留下编号的街道名称。我从末尾(邮政编码)取下数字,但有些拉链上有破折号。第三个是去掉apt数字,它们是#9或#9。我不知道你所说的“永远匹配”是什么意思——它们不是只匹配数字吗?也许我应该说它们总是认为匹配我将编辑我的答案以扩展这一点。
address.gsub(/^\d+|\d+(?:-\d+)?$|\# *\d+/, "")