0

我有以下

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

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

4

3 回答 3

4

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

address = '6 66-666 #99 11-23'
address.gsub(/^\d*|\d*-?\d*$|\# ?\d*/, "")
# " 66-666  "

address = 'pancakes 6 66-666 # pancakes #99 11-23'
address.gsub(/^\d*|\d*-?\d*$|\# ?\d*/,"")
# "pancakes 6 66-666 pancakes  "

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

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

取决于您的数据的真实外观以及您需要如何处理换行符。

于 2011-08-09T18:18:22.827 回答
3

结合正则表达式是一个好主意——而且相对简单——但我想推荐一些额外的改变。以机智:

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

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

您的第三个正则表达式 ,\# ?\d*将匹配任何#字符,如果#后面跟着空格和一些数字,它也会采用这些字符。从您的其他正则表达式和我对其他问题的经验来看,我怀疑您的意思是仅在 a#后跟一个或多个数字时才匹配,并且中间有可选空格。这就是我的第三个正则表达式所做的。

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


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

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

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

于 2011-08-09T19:16:16.063 回答
0

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


例如,这些行中的每一行都从前一个正则表达式替换结果的开头开始。
s/^\d*//g
s/\d*-?\d*$//g
s/\# ?\d*//g

并且这
s/^\d*|\d*-?\d*$|\# ?\d*//g
会在最后一个匹配停止的地方恢复搜索/替换,并且可能会产生不同的整体输出,特别是因为许多子表达式搜索相似
的字符(如果不是相同的字符),仅通过行锚来区分。

我认为您的正则表达式在这种情况下足够独特,当然更改顺序
会改变结果。

于 2011-08-09T19:35:04.273 回答