Pull multiple values from a string using RegEx - ruby

I have the string "{:name=>\"entry 1\", :description=>\"description 1\"}"
I'm using regex to get the values of name and description...
string = "{:name=>\"entry 1\", :description=>\"description 1\"}"
name = /\:name=>\"(.*?)\,/.match(string)
description = /\:description=>\"(.*?)\,/.match(string)
This however only returns name as #<MatchData ":name=>\"entry 1\"," 1:"entry 1\""> and description comes back as nil.
What I ideally want is for name to return "entry 1" and description come back as "description 1"
I'm not sure where I'm going wrong... any ideas?

The problem is the comma in /\:description=>\"(.*?)\,/ should be /\:description=>\"(.*?)/ or /\:description=>\"([^"]+)/
Also you can this method:
def extract_value_from_string(string, key)
%r{#{key}=>\"([^"]+)}.match(string)[1]
end
extract_value_from_string(string, 'description')
=> "description 1"
extract_value_from_string(string, 'name')
=> "name 1"

try this regex to retrieve both name and description at one step
(?<=name=>\\"|description=>\\")[^\\]+
try this Demo
I know this demo is using PCRE but I've tested also on http://rubular.com/ and it works fine
and if you want to get them separately use this regex is to extract name (?<=name=>\\")[^\\]+ and this for description (?<=description=>\\")[^\\]+

Related

Laravel how to replace a words in string

I am trying to change words in string, I know laravel Str::replace() function but it converts if you write exact word. This is what i want to do :
$string = " this is #username and this is #username2"
I want to find usernames which starts with "#" and make them like below, i want to add <strong> html tag them :
$newstring = " this is <strong>#username</strong> and this is <strong>#username2</strong>"
I couldnt find the way to change dynamic value on str replace.
Thanks
Use preg_replace
$string = 'this is #username and this is #username2';
$newString = preg_replace('/(\#\w+)/', '<strong>$1</strong>', $string);
Docs: https://www.php.net/manual/en/function.preg-replace.php

How to implement indirection

How does one indirectly refer to anything? In my case it's a column name. The "Field Access" section of the language doc left me with no clue.
For example
let
OriginalStrings = "some string with {tkn1} and/or {tkn2}"
,ParamTable = [tkn1 = "this", tkn2 = "that"]
,Result = List.Accumulate(Record.FieldNames(ParamTable),OriginalStrings
,(txt,current) => Text.Replace(txt,"{"&current&"}",ParamTable[current]))
in
Result
This results in: Field 'current' of record not found. What I want is the value of 'current' as an identifier and not the literal.
The code above should result in "some string with this and/or that"
Similar to my answer here, Expression.Evaluate may work for what you're after.
Replace ParamTable[current] with
Expression.Evaluate("ParamTable["&current&"]", [ParamTable=ParamTable])
Check out the Expression.Evaluate() and non global environments section of this article for more clarity about the environment argument.

How to store array in a variable in ruby

I need some help working and new with arrays. I am trying to store a value in an email in an instance variable to be used at a later stage of my test. The email body contains the following string
Finally, your Reference Number us 7712342 - please quote this number
So what my tests is going to do is
visit the email page
grab that string and store as str_array = my Array. And I only need the number: 7712342
The problem i have is the email body has a whole bunch of text so not sure how to grab that particular text i need.
Once i have it then im good to carry on with my tests. but im stuck for now.
Hope to find some help with this.
Here is something i quickly wrote.
element :email_form, '.form-control'
element :go_button, '.input-group-btn'
elements :subject, '.all_message-min_text'
def check_email_and_store_ref
email = "test-3#mailinator.com"
email_body = "Finally, your Web Order Reference Number is 7754468 - please quote this in any communication with us until you receive your Subscriber Number."
email_subject_line = find_element_by_text(self.subject.first, email_body, {:text_element => 'header', :partial_match => true})
ref_number = email_bidy.scan(/\d+/)
Capybara.visit 'https://www.mailinator.com/'
email_form.set email
go_button.click
email_subject_line.click
puts ref_number
#I can now use the above ref number in another method within my class
end
Use String#Scan
> email_body = "Finally, your Reference Number us 7712342 - please quote this number"
> reference_no = email_body.scan(/\d+/)
#=> ["7712342"]

just capture the text and remove the email with a regex

I'm trying to make a regex that removes me in my text email: toto#toto.com.
example: I ​​request information on your project email: toto#free.fr
So I did this that captures me "email: toto#toto.com"
message ="I ​​request information on your project email. toto#free.fr"
message.gsub!("/(email: [-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$)/i")
it returns me nothing, and I wish there was just in the message text.
thanks
Try this. This should work for both uppercase, lowercase and emails appear in the middle of the string.
email = /[A-Za-z]{5}:\s[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}/
s = "I request information on your project email: toto#free.fr"
s.match(email).pre_match #=> "I request information on your project "
s2 = "This email: blah#bLAH.com is in the middle"
s2.match(email).pre_match #=> "This "
s2.match(email).post_match #=> " is in the middle"
But there are more cases not covered e.g. email: followed by many spaces
Your code has several problems:
You are looking for "email: ...", but you message has "email. ...".
You use gsub!, with one parameter, which is not the classic use case, and returns an Enumerator. The classic use case expects a second parameter, which indicates to what you want to substitute the found matches:
Performs the substitutions of String#gsub in place, returning str, or
nil if no substitutions were performed. If no block and no replacement
is given, an enumerator is returned instead.
You pass a string to the gsub! - "/(email: [-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$)/i", which is different than sending a regex. To pass a regex, you need to drop the quotes around it: /(email: [-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$)/i
So a fix to your code would look like this:
message ="I ​​request information on your project email: toto#free.fr"
message.gsub!(/(email: [-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$)/i, '')
# => "I ​​request information on your project "
Also note I changed your code to use gsub instead of gsub!, since gsub! changes the underlying string, instead of creating a new one, and unless you have a good reason to do that, it is not encouraged to mutate the input arguments...
If you want to remove the email from the text use String#sub
message = "I ​​request information on your project email. toto#free.fr"
message.sub!(/[A-Za-z]{5}:\s[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}/, '')
# => "I ​​request information on your project "

How do I use gsub to search and replace using a regex?

I want to filter tags out of a description string, and want to make them into anchor tags. I am not able to return the value of the tag.
My input is:
a = "this is a sample #tag and the string is having a #second tag too"
My output should be:
a = "this is a sample #tag and the string is having a #second tag too"
So far I am able to do some minor stuff but I am not able to achive the final output. This pattern:
a.gsub(/#\S+/i, "<a href='/tags/\0'>\0</a>")
returns:
"this is a sample <a href='/tags/\u0000'>\u0000</a> and the string is having a <a href='/tags/\u0000'>\u0000</a> tag too"
What do I need to do differently?
You can do it like this:
a.gsub(/#(\S+)/, '\0')
The reason why your replacement doesn't work is that you must use double escape when you are between double quotes:
a.gsub(/#(\S+)/, "<a href='/tags/\\1'>\\0</a>")
Note that the /i modifier is not needed here.
You need to give gsub a block if you want to do something with the match from the regex:
a.gsub(/#(\S+)/i) { "<a href='/tags/#{$1}'>##{$1}</a>" }
$1 is a global variable that Ruby automatically fills with the first capture block in the matched string.
Try this:
a.gsub(/(?<a>#\w+)/, '\k<a>')

Resources