Does flowgrounds JSONata expressions support regex? - jsonata

I'm trying to build a fairly complex expression with a CBR where I try to identify if a string contains another string. In order to do so I need to manipulate the second string and use a little bit of regex magic but it doesn't seem to work. Could anyone confirm if the JSONata implementation of flowground support regex inside a "contains" operation? The expression I am using right now is the following:
$not($contains(elements[0].attribs.content,"/" & $replace(elasticio."step_1".body.issue.fields."customfield_22519"[0],"-"," ") &"/i"))

RegEx and $contains are working correctly in combination.
The reason for your not working expression is that the second parameter of $contains is a string (something like "/xyz/i"). This string is not being interpreted as a regex.
your expression: $contains( "abc", "/" & "X" & "/i")
to change in: $contains( "abc", $eval("/" & "B" & "/i") )

Related

This RegEx is not working when I use RegEx Class

I have written the following code
policy="Policy: SCW000359-18\nAB & A Abcdef"
p policy[/(?<=Policy:) \w+-\w+/]
It works so perfectly, it prints the following result
" SCW000359-18"
But I have to receive the regular expression as a string parameter so I have written the following code
p policy[/#{Regexp.quote("(?<=Policy:) \w+-\w+")}/]
But it's returning nil. Can anyone help me?
RegExp.quote will quote the metacharacters in the regexp, so it is going to search for the literal string: (?<=Policy:) \w+-\w+, which obviously is not in your search string Policy: SCW000359-18\nAB & A ….
In this case you should not quote the regex string and instead use:
Regexp.new('(?<=Policy:) \w+-\w+')
Docs

Extract values after pattern in Ruby string

I have a string like this:
"<root><some ProdCode=\"40\" ProducerName=\"demo1\" ProdCode=\"40\" Need_Confirmation=\"1\"/><some ProdCode=\"40\" ProducerName=\"demo1\" ProdCode=\"40\" Need_Confirmation=\"1\"/></root>"
I'm trying to pull the content from this string which is between =\"content\" and put it in an array, like ["40","demo1","40","1",40......]
You should use :scan to select elements by regexp pattern. Then remove escape characters.
string.scan(/"[^"]+"/).map { |element| element.delete('\\"') }
Explanation of pattern:
/ – regexp starts
" – first char should be "
[^"]+ – next should be any char except ". + sign says that number of such chars should be at least 1.
" – next should be again "
/ – regexp ends
So string.scan(/"[^"]+"/) would return:
["\"40\"", "\"demo1\"", "\"40\"", "\"1\"", "\"40\"", "\"demo1\"", "\"40\"", "\"1\""]
Then we can just delete \" using :delete method.
Convenient tool to build regexps is http://rubular.com/
When your string is this simple you can use scan + regular expression like this:
result = html.scan(/ProdCode="\d+?"/)
If it is more complex you can use a html parser like nokogiri or oga.

How can I select quoted strings that are outside html tags?

I am working on a syntax highlighter in ruby. From this input string (processed per line):
"left"<div class="wer">"test"</div>"right"
var car = ['Toyota', 'Honda']
How can I find "left", and "right" in the first line, 'Toyota', and 'Honda' on the second line?
I have (["'])(\\\1|[^\1]*?)\1 to highlight the quoted strings. I am struggling with the negative look behind part of the regex.
I tried appending another regex (?![^<]*>|[^<>]*<\/), but I can't get it to work with quoted strings. It works with simple alphanumeric only.
You can match one or more tokens by creating groups using parentheses in regex, and using | to create an or condition:
/("left")|("right")|('Toyota')|('Honda')/
Here's an example:
http://rubular.com/r/C8ONnxKYEV
EDIT
Just saw the tile of your question specified that you want to search outside HTML tags.
Unfortunately this isn't possible using only Regular expressions. The reason is that HTML, along with any language that requires delimiters like "", '', (), aren't regular. In other words, regexes don't contain a way of distinguishing levels of nesting and therefore you'll need to use a parser along with your Regex. If you're doing this strictly in Ruby, consider using a tool like Nokogiri or Mechanize to properly parse and interact with the DOM.
Description
This Ruby script first finds and replaces the HTML tags, note this is not perfect, and is susceptible to many edge cases. Then the script just looks for all the single and double quoted values.
str = %Q["left" <div class="wer">"test"</div>"right"\n]
str = str + %Q<var car = ['Toyota', 'Honda']>
puts "SourceString: \n" + str + "\n\n"
str.gsub!(/(?:<([a-z]+)(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?>).*?<\/\1>/i, '_')
puts "SourceString after replacement: \n" + str + "\n\n"
puts "array of quoted values"
str.scan(/"[^"]*"|'[^']*'/)
Sample Output
SourceString:
"left" <div class="wer">"test"</div>"right"
var car = ['Toyota', 'Honda']
SourceString after replacement:
"left" _"right"
var car = ['Toyota', 'Honda']
=> ["\"left\"", "\"right\"", "'Toyota'", "'Honda'"]
Live Example
https://repl.it/CRGo
HTML Parsing
I do recommend using an HTML parsing engine instead. This one seems pretty decent for Ruby: https://www.ruby-toolbox.com/categories/html_parsing

Ruby Regex Group Replacement

I am trying to perform regular expression matching and replacement on the same line in Ruby. I have some libraries that manipulate strings in Ruby and add special formatting characters to it. The formatting can be applied in any order. However, if I would like to change the string formatting, I want to keep some of the original formatting. I'm using regex for that. I have the regular expression matching correctly what I need:
mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, 'New Text')
However, what I really want is the matching from the first grouping found in:
(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))
to be appended to New Text and replaced as opposed to just New Text. I'm trying to reference the match in the form of
mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, '\1' + 'New Text')
but my understanding is that \1 only works when using \d or \k. Is there any way to reference that specific capturing group in my replacement string? Additionally, since I am using an asterik for the [], I know that this grouping could occur more than once. Therefore, I would like to have the last matching occurrence yielded.
My expected input/output with a sample is:
Input: "\e[1mHello there\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"
Input: "\e[1mHello there\e[44m\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"
So the last grouping is found and appended.
You can use the following regex with back-reference \\1 in the replacement:
reg = /(\\e\[(?:[0-9]{1,2}|[3,9][0-8])m)+Text/
mystring = "\\e[1mHello there\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
mystring = "\\e[1mHello there\\e[44m\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
Output of the IDEONE demo:
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
Mind that your input has backslash \ that needs escaping in a regular string literal. To match it inside the regex, we use double slash, as we are looking for a literal backslash.

Ruby string sub without regex back references

I'm trying to do a simple string sub in Ruby.
The second argument to sub() is a long piece of minified JavaScript which has regular expressions contained in it. Back references in the regex in this string seem to be effecting the result of sub, because the replaced string (i.e., the first argument) is appearing in the output string.
Example:
input = "string <!--tooreplace--> is here"
output = input.sub("<!--tooreplace-->", "\&")
I want the output to be:
"string \& is here"
Not:
"string & is here"
or if escaping the regex
"string <!--tooreplace--> is here"
Basically, I want some way of doing a string sub that has no regex consequences at all - just a simple string replace.
To avoid having to figure out how to escape the replacement string, use Regex.escape. It's handy when replacements are complicated, or dealing with it is an unnecessary pain. A little helper on String is nice too.
input.sub("<!--toreplace-->", Regexp.escape('\&'))
You can also use block notation to make it simpler (as opposed to Regexp.escape):
=> puts input.sub("<!--tooreplace-->") {'\&'}
string \& is here
Use single quotes and escape the backslash:
output = input.sub("<!--tooreplace-->", '\\\&') #=> "string \\& is here"
Well, since '\\&' (that is, \ followed by &) is being interpreted as a special regex statement, it stands to reason that you need to escape the backslash. In fact, this works:
>> puts 'abc'.sub 'b', '\\\\&'
a\&c
Note that \\\\& represents the literal string \\&.

Resources