从Rails字符串中提取子字符串的中间部分。

huangapple go评论129阅读模式
英文:

Extracting substring from the middle of a string in Rails

问题

I'm trying to extract a substring from a class type returned as a string:

  1. '::Pos::EmailNotice'
  2. 'Pos::EmailNotice'
  3. '::Pos::CallNotice'
  4. 'Pos::CallNotice'

So if I get a string 'Pos::{type}Notice', I would need to end up with {type}.

I've tried to use #slice as well as #delete_prefix and #delete_suffix but I'd like it to be more dynamic than that just in case the namespacing gets changed or we add more types of notices in the future.

I tried searching here but I couldn't find any answers explaining how to extract text in a case like this.

英文:

I'm trying to extract a substring from a class type returned as a string:

  1. '::Pos::EmailNotice'
  2. 'Pos::EmailNotice'
  3. '::Pos::CallNotice'
  4. 'Pos::CallNotice'

So if I get a string 'Pos::{type}Notice', I would need to end up with {type}.

I've tried to use #slice as well as #delete_prefix and #delete_suffix but I'd like it to be more dynamic than that just in case the namespacing gets changed or we add more types of notices in the future.

I tried searching here but I couldn't find any answers explaining how to extract text in a case like this.

答案1

得分: 1

假设它始终以 Notice 结尾,那么这可能是最简单的:

  1. %w[::Pos::EmailNotice Pos::EmailNotice ::Pos::CallNotice Pos::CallNotice ].map do |s|
  2. s.match(/([^:]+)Notice/)[1]
  3. end
  4. ["Email", "Email", "Call", "Call"]

基本上是说“在 'Notice' 之前的所有非 ':' 字符”。

英文:

Assuming it always ends in Notice then this is probably the simplest:

  1. main> %w[ ::Pos::EmailNotice Pos::EmailNotice ::Pos::CallNotice Pos::CallNotice ].map do |s|
  2. main> s.match(/([^:]+)Notice/)[1]
  3. main> end
  4. ["Email", "Email", "Call", "Call"]

Which is basically saying "all non ':' chars before 'Notice'".

答案2

得分: 1

arr = [ "Pos::EmailNotice",
"Pos::EmailNotice",
"Pos::CallNotice",
"Pos::CallNotice"
]

arr.map { |str| str[/[^:]*(?=Notice\z)/] }

Demo

The demo employs the PCRE regex engine. Though different in some ways to Ruby's Onigmo regex engine, in this case they give the same result. I've used the end-of-line anchor ($) rather than the end-of-string anchor (\z) in order to test the expression against multiple strings.

This employs the method String#[] with a regular expression as its argument.

The regular expression reads, "Match zero or more (*) characters other than (^) a colon to be followed by the literal "Notice" at the end of the string (\z)".

(?=Notice\z) is a positive lookahead.

You may wish to hover the cursor over each part of the regular expression at the link to obtain an explanation of its function.

英文:
  1. arr = [ "::Pos::EmailNotice",
  2. "Pos::EmailNotice",
  3. "::Pos::CallNotice",
  4. "Pos::CallNotice"
  5. ]

<!-->
arr.map { |str| str[/[^:]*(?=Notice\z)/] }
#=> ["Email", "Email", "Call", "Call"]


Demo

The demo employs the PCRE regex engine. Though different in some ways to Ruby's Onigmo regex engine, in this case they give the same result. I've used the end-of-line anchor ($) rather than the end-of-string anchor (\z) in order to test the expression against multiple strings.

This employs the method String#[] with a regular expression as its argument.


The regular expression reads, "Match zero or more (*) characters other than (^) a colon to be followed by the literal "Notice" at the end of the string (\z)".

(?=Notice\z) is a positive lookahead.

You may wish to hover the cursor over each part of the regular expression at the link to obtain an explanation of its function.

答案3

得分: 1

Rails提供了String#demodulize来去除模块的命名空间:

  1. '::Pos::EmailNotice'.demodulize #=> "EmailNotice"
  2. 'Pos::EmailNotice'.demodulize #=> "EmailNotice"
  3. '::Pos::CallNotice'.demodulize #=> "CallNotice"
  4. 'Pos::CallNotice'.demodulize #=> "CallNotice"

你可以与delete_suffix!一起使用,例如:

  1. string = '::Pos::EmailNotice'
  2. string.demodulize.delete_suffix!('Notice')
  3. #=> "Email"

另一种方法是将字符串转换为实际的类,并让它实现一个type方法,你可以调用它,例如:

  1. module Pos
  2. class EmailNotice
  3. def self.type
  4. :email
  5. end
  6. end
  7. end

然后,你可以使用Rails的String#constantize

  1. '::Pos::EmailNotice'.contantize.type #=> :email
  2. 'Pos::EmailNotice'.contantize.type #=> :email

或者使用纯Ruby通过Module#const_get

  1. Object.const_get('::Pos::EmailNotice').type #=> :email
  2. Object.const_get('Pos::EmailNotice').type #=> :email
英文:

Rails provides String#demodulize to strip the namespace off a module:

  1. &#39;::Pos::EmailNotice&#39;.demodulize #=&gt; &quot;EmailNotice&quot;
  2. &#39;Pos::EmailNotice&#39;.demodulize #=&gt; &quot;EmailNotice&quot;
  3. &#39;::Pos::CallNotice&#39;.demodulize #=&gt; &quot;CallNotice&quot;
  4. &#39;Pos::CallNotice&#39;.demodulize #=&gt; &quot;CallNotice&quot;

You could use that along with delete_suffix!, e.g.

  1. string = &#39;::Pos::EmailNotice&#39;
  2. string.demodulize.delete_suffix!(&#39;Notice&#39;)
  3. #=&gt; &quot;Email&quot;

Another approach would be to convert the string to the actual class and have it implement a type method that you can call, e.g.:

  1. module Pos
  2. class EmailNotice
  3. def self.type
  4. :email
  5. end
  6. end
  7. end

You could then use Rails' String#constantize:

  1. &#39;::Pos::EmailNotice&#39;.contantize.type #=&gt; :email
  2. &#39;Pos::EmailNotice&#39;.contantize.type #=&gt; :email

or with pure Ruby via Module#const_get:

  1. Object.const_get(&#39;::Pos::EmailNotice&#39;).type #=&gt; :email
  2. Object.const_get(&#39;Pos::EmailNotice&#39;).type #=&gt; :email

答案4

得分: 0

以下是翻译好的部分:

  1. str = [&#39;::Pos::EmailNotice&#39;, &#39;Pos::EmailNotice&#39;,
  2. &#39;::Pos::CallNotice&#39;, &#39;Pos::CallNotice&#39;, &#39;Pos::CallText&#39;]

使用 gsub

  1. str.map {|i| i.gsub /.*::|(Notice|Text)$/, &quot;&quot;}
  2. [&quot;Email&quot;, &quot;Email&quot;, &quot;Call&quot;, &quot;Call&quot;, &quot;Call&quot;]

如果您需要更多帮助,请随时提问。

英文:

Test strings

  1. str = [&#39;::Pos::EmailNotice&#39;, &#39;Pos::EmailNotice&#39;,
  2. &#39;::Pos::CallNotice&#39;, &#39;Pos::CallNotice&#39;, &#39;Pos::CallText&#39;]

Using gsub

  1. str.map {|i| i.gsub /.*::|(Notice|Text)$/, &quot;&quot;}
  2. [&quot;Email&quot;, &quot;Email&quot;, &quot;Call&quot;, &quot;Call&quot;, &quot;Call&quot;]

huangapple
  • 本文由 发表于 2023年7月28日 05:41:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76783559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定