[英]Using Ruby gsub with regex as replacement
Ruby gsub支持使用正则表达式作为模式来检测输入,它也可能允许使用匹配组号来替换
例如,如果这是一个检测任何单词开头的小写字母的正则表达式,并在它之前放置一个x
在它之后放置一个y
这将给出完美的结果:
"testing gsub".gsub(/(?<=\b)[a-z]/,'x\0y')
#=> "xtyesting xgysub"
但是,如果我想使用正则表达式将此匹配组转换为普通正则表达式中的大写,通常可以按照此处的说明执行此\\U\\$0
不幸的是,当我这样尝试时:
"testing gsub".gsub(/(?<=\b)[a-z]/,'\U\0')
#=> "\\Utesting \\Ugsub"
另外,如果我尝试在替换字段中使用原始正则表达式,如下所示:
"testing gsub".gsub(/(?<=\b)[a-z]/,/\U\0/)`
我收到类型错误:
TypeError (no implicit conversion of Regexp into String)
我完全知道使用这样的地图来做这件事的选项:
"testing gsub".gsub(/(?<=\b)[a-z]/,&:upcase)
但不幸的是,规则(模式、替换)是从 .yaml 文件加载的,它们以这种方式应用于字符串:
input.gsub(rule['pattern'], rule['replacement'])
我无法将&:upcase
存储在 .yaml 中以作为原始字符串
我可能会做的一个解决方法是检测 upcase 是否是“upcase”的替代品,然后这样做
"testing gsub".gsub(/(?<=\b)[a-z]/) {|l| l.send("upcase")}
但我不想修改这个逻辑:
input.gsub(rule['pattern'], rule['replacement'])
如果有一种解决方法可以在gsub
替换中使用正则表达式,或者在 YAML 中存储&:upcase
类的方法而不作为字符串加载,那将是完美的。
谢谢!
你不能做你想做的,你想要的方式。 这在 Onigmo 源中有记录。 您必须使用不同的方法,或重构代码的其他区域来模拟您想要的行为。
\\U
转义在 Ruby 中不可用像\\U
这样的特殊转义符是对 GNU sed 的扩展或从 PCRE 库移植。 它们不是 Ruby 当前正则表达式引擎的一部分。 Onigmo 消息来源清楚地提到缺少这些转义:
A-3. Missing features compared with perl 5.18.0 + \\N{name}, \\N{U+xxxx}, \\N + \\l,\\u,\\L,\\U, \\C + \\v, \\V, \\h, \\H + (?{code}) + (??{code}) + (?|...) + (?[]) + (*VERB:ARG)
您可以通过多种不同的方式执行您想要的操作,例如使用String#gsub的块形式在每次匹配时调用String#upcase 。 例如:
"testing gsub".gsub(/\b\p{Lower}+/) { |m| m.upcase }
#=> "TESTING GSUB"
如果您想可靠地引用某些匹配变量(如$&
或$1
,您还必须使用块形式,否则这些变量可能会引用先前匹配中的文本。 为了说明,请考虑:
"foo bar".gsub /\b\p{Lower}+/, "#{$&.upcase}"
#=> "BAR BAR"
由于这主要是一个 X/Y 问题,如果您发布一个相关问题,其中包含 YAML 源示例和用于解析正则表达式匹配/替换的当前代码,您可能会对收到的答案感到满意。 也许有一种您没有考虑过的包装或重构代码的方法,但是您将无法按照您想要的方式解决这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.