【问题标题】:Regex (ruby) to remove all instances of a set of characters EXCEPT when they are at the start of a string正则表达式(ruby)删除一组字符的所有实例,除非它们位于字符串的开头
【发布时间】:2019-04-05 14:51:17
【问题描述】:

我想从字符串中删除这些字符["+", "-", "~"] 的所有实例,除非它们出现在字符串的开头。

例如:

"abc"   => "abc"
"ab+c"  => "abc"
"+abc"  => "+abc"
"-+abc" => "-abc"
"ab+-c" => "abc"

注意第四个 + 被删除,因为它不是第一个字符。所以,如果一个字符串的开头有多个“不需要的”字符,我们只保留第一个。

我不太明白这个正则表达式的语法。任何人都可以帮忙吗?我正在使用 Ruby,但正则表达式语法 往往 跨语言是相同的。

【问题讨论】:

  • 语言有所不同,因为 Ruby 正则表达式有些特定(尤其是在 string 匹配开始时)。到目前为止你有没有尝试过任何模式?
  • 我试过了,但它没有改变字符串:"+ab-c"..gsub(/^(![\+\-\~])/,"")
  • 请将其添加到问题中。
  • 非正则表达式解决方案:str[1..-1] = str[1..-1].delete('+~-')
  • @Stefan 在 ruby​​ 2.6+ 中我们现在可以使用str[1..] 代替str[1..-1]。另外 OP 小心使用 '+~-' 而不是 '+-~' 因为第一个将删除这 3 个字符,第二个将删除 + (43) 和 ~ (126) 之间的所有字符,因为查看了 -在这种情况下引用一系列字符

标签: regex ruby


【解决方案1】:

^(![\+\-\~] 模式匹配 的开头,然后将 ! 字符后跟 +-~ 字符捕获到第 1 组中,因此您删除仅!+!~!- 位于行首。

你可以使用

/(?!\A)[+~-]/

它匹配任何不在字符串开头 ((?!\A)) 的 +~- 字符 ([+~-])。 (?!\A) 是一个否定的前瞻,如果它的模式没有立即匹配到当前位置的右侧,则匹配失败。如果该位置位于字符串的开头(\A assets 这个位置),则匹配失败。由于\A 是一个不消耗任何文本的锚点,即所谓的零长度模式,因此如果使用前瞻或后瞻,(?<!\A) 没有区别。

确保- 位于字符类的开头或结尾,您不必转义它。

Ruby demo:

strs = ["abc", "ab+c", "+abc", "-+abc", "ab+-c"]
strs.each { |x| p x.gsub(/(?!\A)[-+~]/, "") }

输出:

"abc"
"abc"
"+abc"
"-abc"
"abc"

【讨论】:

  • 效果很好,谢谢! "-+ab-c+d".gsub(/(?!\A)[+~-]/,"") => "-abcd"。那么,(?!\A) 的意思是“不是开始”? \A 在做什么?
  • 另一种(不太理想的)方式:"-cats+dogs".gsub(/(.)[+~-]/, '\1') => "-catsdogs".
  • 我也想过这个办法,但是特意没有补充。
  • 我也不会添加它,因为我们的共同信念是包含不太理想的解决方案只会淡化答案,但同时我认为值得在评论中提及。人们永远不知道什么时候对一个问题采用低劣的方法可能会导致另一个问题的良好解决方案(尽管我猜任何答案都可以在此基础上得到证明)。
  • @MaxWilliams 然后要完成这个对话,你实际上会使用.gsub(/(.)[+~-]/m, '\1'),因为默认情况下. 不匹配换行符并且需要m 标志。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-01
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
相关资源
最近更新 更多