0

Ok, so let me explain. I have some string like this : "BAHDGF - ZZZGH1237484" or like this "HDG54 - ZZZ1HDGET4" I want here to select the triple Z (that are obviously 3 differents character but for the example I think it's more comprehensible for you).

So, my problem is the next : The first part has a modulable length but i can just ignore it, I need something to take the triple Z so I was thinking about something that can "slice" my string after the " - ".

I started to try using "partition" but I just failed lamentably. I just get kinda lost with the news 3 array and then take the first 3 letter of one of the array, well, it seems very complicated and i think I'm just passing by an obvious solution that I can't find actually. It's been something like 2 days that i'm on it without anything in my mind that can help me, sort of blank page syndrome actually and I really need a little help to unlock this point.

  • I don't use ruby but [regular expressions exist in ruby](https://ruby-doc.org/core-2.5.1/Regexp.html). Hopefully someone comes along to help you implement it, but that'll help you solve it. A working pattern that captures those three characters `.*?\s-\s(.{3})` (which you can test [here](https://regex101.com/)). What you want is the first (and only) capture group from a match with that pattern. Note that in the future, you can also just **bold** the characters you want, but your message was clear here. – Kraigolas Mar 19 '21 at 00:12

2 Answers2

1

Given:

examples=[ "BAHDGF - ZZZGH1237484", "HDG54 - ZZZ1HDGET4" ]

You could use a regex:

examples.each {|e| p e, e[/(?<=-\s)ZZZ/]}

Prints:

"BAHDGF - ZZZGH1237484"
"ZZZ"
"HDG54 - ZZZ1HDGET4"
"ZZZ"

Or .split with a regex:

examples.each {|e| p e.split(/-\s*(ZZZ)/)[1] }
'ZZZ'
'ZZZ'

If the 3 characters are something other than 'ZZZ' just modify your regex:

> "BAHDGF - ABCGH1237484".split(/\s*-\s*([A-Z]{3})/)[1]
=> "ABC"

If you wanted to use .partition it is two steps. Easiest with a regex partition and then just take the first three characters:

> "BAHDGF - ABCGH1237484".partition(/\s*-\s*/)[2][0..2]
=> "ABC"
dawg
  • 98,345
  • 23
  • 131
  • 206
0

"Selecting" the string "ZZZ" is a misnomer. What you have asked for is to determine if the string contains the substring "- ZZZ" and if it does, return "ZZZ":

"BAHDGF - ZZZGH1237484".include?("- ZZZ") && "ZZZ"
  #=> "ZZZ"

"BAHDGF - ZZVGH1237484".include?("- ZZZ") && "ZZZ"
  #=> false

That is very little different that just asking if the string contains the substring "- ZZZ":

if "BAHDGF - ZZZGH1237484".include?("- ZZZ")
  ...
end 

If the question were instead, say, return a string of three identical capital letters following "- ", if present, you would be selecting a substring. That could be done as follows.

r = /- \K(\p{Lu})\1{2}/

"BAHDGF - XXXGH1237484"[r]
  #=> "XXX"

"BAHDGF - xxxGH1237484"[r]
  #=> nil

The regular expression reads, "match '- ', then forget everything matched so far and reset the match pointer to the current location (\K), then match an upper case Unicode letter (\p{Lu}) and save it to capture group 1 ((\p{Lu})), then match the contents of capture group 1 (\1) twice ({2})". One may alternatively use a positive lookbehind:

/(?<=- )(\p{Lu})\1{2}/
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100