The first image below is the parent workflow and the image below that is the child workflow. In the child workflow I check if a singular value I provide is in the list separated by commas I also provide. I use a Regex matcher along with an if node to do this. The problem is the Regex matcher continues to execute for all matches although I want it to stop checking # 2016/05/13 09:08:30, when the expression evaluates to true (the word 'Contract' is present in 'Contract,VMS,Payroll'). I want the Regex matcher to stop and then output isTrue boolean to the variable bar so the parent workflow gets a 'true' instead of the false which it gets now. (which you can see happens in the last activity entry 2016/05/13 09:08:30 where Value is false (since it gets the LAST updated value) for the child workflow).
Hmmm..... There isn't a way to break out of that loop but you should be able to use Regex Match One instead of the loop version as you're actually only interested in determining whether a given pattern matches rather than needing to iterate over each match in order to process it further.
Yes or if its really just s simple string match, use the If Node with expression 'Value like "matchexpression" '
Related
I have a below string array object which has 4 elements. I want to compare the elements of this list to an string and want to check if string is part of this list.
list = ["starter_v2", "professional_q", "custom_v", "basic_t9"]
str = "starter"
if list.include?str #should return true but returning false as it is checking the full string not the substring
Above if condition should return true, however it is returning false.
Can someone suggest me how to fix this, as I am new to ruby and want to compare strings.
For my usecase, in list object I will always have entries with "_" followed by an alphabetic character and I will compare this by string without "_"
Enumerable#include? checks if a given value matches any value in the given enumerable. A substring is not equivalent to a string that contains it, so this check fails.
Instead, you want to check if any string in the array matches your substring. Ruby has handy facilities for this: Enumerable#any? lets you iterate an enumerable, yielding each element to a block, and then will return true if any invocation of the block returns true.
So, you can use:
list.any? {|element| element.include?(str) }
What this will do is check each entry in list to see if str is included in it; once a match is found, it'll stop iterating and return true. If it goes through the entire list without finding a match, it'll return false.
You could also use use element.start_with? if you know that your search string should always match the first part of the string, or you could use a more complex condition which splits each element on underscore and compares the first part, or you could use a regex. The important part is that the block returns true when you want to indicate a match.
I'd like to make a string substitution in a for block using a named capture. I've expected to get the numbers 1,2,3 as output. But it is Nil for the first run, and then 1 and 2 for the 2nd and 3rd run. How do I use the .subst correctly in the loop construct? I see the same behavior when using a map construct instead the for loop. It does work as expected, if I replace with a fixed string value.
for <a1 b2 c3> -> $var {
say $var;
say $var.subst(/.$<nr>=(\d)/, $<nr>); #.subst(/.$<nr>=(\d)/, 'X'); #OK
}
#`[
This is Rakudo version 2019.11 built on MoarVM version 2019.11
Output:
a1
Use of Nil in string context
in block at test3.pl6 line 3
b2
1
c3
2
]
TL;DR Defer evaluation of $<nr> until after evaluation of the regex. #JoKing++ suggests one way. Another is to just wrap the replacement with braces ({$<nr>}).
What happens when your original code calls subst
Before Raku attempts to call the subst routine, it puts together a list of arguments to pass to it.
There are two values. The first is a regex. It does not run. The second value is $<nr>. It evaluates to Nil because, at the start of a program, the current match object variable is bound to something that claims its value is Nil and any attempt to access the value of a key within it -- $<nr> -- also returns Nil. So things have already gone wrong at this point, before subst ever runs.
Once Raku has assembled this list of arguments, it attempts to call subst. It succeeds, and subst runs.
To get the next match, subst runs the regex. This updates the current match object variable $/. But it's too late to make any difference to the substitution value that has already been passed to subst.
With match in hand, subst next looks at the substitution argument. It finds it's Nil and acts accordingly.
For the second call of subst, $<nr> has taken on the value from the first call of subst. And so on.
Two ways to defer evaluation of $<nr>
#JoKing suggests considering use of S///. This construct evaluates the regex (between the first pair of /s) first, then the replacement (between the last pair of /s). (The same principle applies if you use other valid S syntaxes like S[...] = ....)
If you use subst, then, as explained in the previous section, Raku puts together the argument list for it before calling it. It finds a regex (which it does not run) and a closure (which it does not run either). It then attempts to call subst with those arguments and succeeds in doing so.
Next, subst starts running. It has received code for both the match (a regex) and the substitution (a closure).
It runs the regex as the matching operation. If the regex returns a match then subst runs the closure and uses the value it returns as the substitution.
Thus, because we switched from passing $<nr> as a naked value, which meant it got frozen into Nil, to passing it wrapped in a closure, which deferred its evaluation until $/ had been set to a match with a populated <nr> entry, we solved the problem.
Note that this only works because whoever designed/implemented subst was smart/nice enough to allow both the match and substitution arguments to be forms of Code (a regex for the match and ordinary closure for the substitution) if a user wants that. It then runs the match first and only then runs the substitution closure if it's been passed one, using the result of that latter call as the final substitution. Similarly, S/// works because that has been designed to only evaluate the replacement after it's first evaluated the substitution.
In Selenium I have written a xpath and both of them retrieves the same result.
//a[#role='tab'][text()=' Assets']
//a[#role='tab' and text()=' Assets']
Does both of them have the same meaning?
In most cases a[b][c] has exactly the same effect as a[b and c]. There are two exceptions to be aware of:
They are not equivalent if either predicate is numeric, or has a dependency on position() or last() (I call these positional predicates). For example a[#x][1] selects the first a element that has an #x attribute, while a[1][#x] selects the first a element provided it has an #x attribute (and selects nothing otherwise). By contrast a[1 and #x] converts the integer 1 to the boolean true(), so it just means a[#x].
There may be differences in behaviour if evaluation of b or c fails with a dynamic error. The precise rules here depend on which version of XPath you are using, and to be honest the rules leave implementations some leeway, but you need to exercise care if you want to be sure that in the event of b being false, c is not evaluated. (This hardly matters in XPath 1.0 because very few expressions throw dynamic errors.)
When you add Square Brackets ([]) to XPath you are adding a condition, so
first row adding 2 conditions
Which produce similar results as adding condition with and
Normally you don't use first row, because it less readable,
Mainly because this syntax represent in other languages a Matrix
// return a random m-by-n matrix with values between 0 and 1
public static double[][] random(int m, int n) {
See tutorial:
5 XPaths with predicates
A predicate is an expression that can be true or false
It is appended within [...] to a given location path and will refine results
More than one predicate can be appended to and within (!) a location path
The first one is a predicate, which means it checks if a[#role='tab'] is true then it proceeds to [text()=' Assets']
The second one is a just using an and operator so it validates both are true.
I don't fully understand, why the results are different here. Does :ov apply only to <left>, so having found the longest match it wouldn't do anything else?
my regex left {
a | ab
}
my regex right {
bc | c
}
"abc" ~~ m:ex/<left><right>
{put $<left>, '|', $<right>}/; # 'ab|c' and 'a|bc'
say '---';
"abc" ~~ m:ov/<left><right>
{put $<left>, '|', $<right>}/; # only 'ab|c'
Types of adverbs
It's important to understand that there are two different types of regex adverbs:
Those that fine-tune how your regex code is compiled (e.g. :sigspace/:s, :ignorecase/:i, ...). These can also be written inside the regex, and only apply to the rest of their lexical scope within the regex.
Those that control how regex matches are found and returned (e.g. :exhaustive/:ex, :overlap/:ov, :global/:g). These apply to a given regex matching operation as a whole, and have to be written outside the regex, as an adverb of the m// operator or .match method.
Match adverbs
Here is what the relevant adverbs of the second type do:
m:ex/.../ finds every possible match at every possible starting position.
m:ov/.../ finds the first possible match at every possible starting position.
m:g/.../ finds the first possible match at every possible starting position that comes after the end of the previous match (i.e., non-overlapping).
m/.../ finds the first possible match at the first possible starting position.
(In each case, the regex engine moves on as soon as it has found what it was meant to find at any given position, that's why you don't see additional output even by putting print statements inside the regexes.)
Your example
In your case, there are only two possible matches: ab|c and a|bc.
Both start at the same position in the input string, namely at position 0.
So only m:ex/.../ will find both of them – all the other variants will only find one of them and then move on.
:ex will find all possible combinations of overlapping matches.
:ov acts like :ex except that it limits the search algorithm by constraining it to find only a single match for a given starting position, causing it to produce a single match for a given length. :ex is allowed to start from the very beginning of the string to find a new unique match, and so it may find several matches of length 3; :ov will only ever find exactly one match of length 3.
Documentation:
https://docs.perl6.org/language/regexes
Exhaustive:
To find all possible matches of a regex – including overlapping ones – and several ones that start at the same position, use the :exhaustive (short :ex) adverb
Overlapping:
To get several matches, including overlapping matches, but only one (the longest) from each starting position, specify the :overlap (short :ov) adverb:
tl;dr
When I use my variable created in Regular Expression Extractor I cannot use it in Random Variable as Maximum Value
Long description:
My test structure:
I have variable my_test what is crated in Regular Expression Extractor
request: GET //echo.getpostman.com/get?test=123
regex:
Then I want it use as Maximum Value in Regular Expression Extractor
So finally I can make request:
//echo.getpostman.com/get?test=${rand}
Unfortunately I get error from Random Variable
2016/10/07 07:52:41 ERROR - jmeter.config.RandomVariableConfig: maximum(${my_test}) must be > minimum1)
Why my_test is not evaluated?
I have tried ${__javaScript(parseInt('${my_test}'))} but it looks like it is evaluated before my variable initialization
2016/10/07 08:06:01 ERROR - jmeter.config.RandomVariableConfig: maximum(NaN) must be > minimum1)
If I initialize this variable in Test Plan in User Defined Variables value from that setting will be used - not updated by regex.
I know that I can do //echo.getpostman.com/get?test=${__Random(0,${my_test})}
I'm just curious how pass my variable as value for Maximum Value in Regular Expression Extractor.
Random Variable is a Config Element and it will be executed first before any other components get executed first.
4.9 Execution order
Configuration elements
Pre-Processors
Timers
Sampler
Post-Processors (unless SampleResult is null)
Assertions (unless SampleResult is null)
Listeners (unless SampleResult is null)
If two or more Config elements present in the Test Plan, then they will be executed in the order they appear in the Test Plan.
Check the execution order and Scope here:
Refer 4.9 7 4.10 here Execution Order and Scope Rules
So, first Random Variable is evaluated first and then Sampler and then regular expression extractor.
When you used User Defined Variables, which is another Config Element, and probably you put it before Random Variable, so it evaluated the expression as you already defined the value for "my_test". But it won't override the value you captured in Regular Expression Extractor.
To solve your problem (one probable solution):
you can use different thread groups. In first thread group, you capture the value and in second thread group, you use the value.
Run Thread Groups consecutively.
Use BeanShell Assertion to capture the value by setProperty. (in first thread group)
Use value using __property() (in thread group)
https://www.blazemeter.com/blog/knit-one-pearl-two-how-use-variables-different-thread-groups
It seems that Random Variable element does not evaluate variables, maybe it worth creating an issue in JMeter Issue Tracker
As a workaround you can substitute it with __Random() function directly where required like:
${__Random(1,${my_test},)} - if you need the value right away, directly in you URL:
//echo.getpostman.com/get?test=${__Random(1,${my_test},)}
${__Random(1,${my_test},rand)} - if if you need to store the value into ${rand} variable as well
See:
Using JMeter Functions article for extended information on this and others JMeter Functions.
Function Helper Dialog - an utility helping to generate correct function syntax.
I think it's valid for me to comment on a problem I had, I set the random variable and it didn't work at all, I did everything I could to try to solve it.
In the end my problem was a space at the beginning of the variable.
One possibility is you can use a Beanshell Postprocessor to write the RegEx value to the variable name.
After that you can use it as ${variable_name}
NB: Beanshell function vars.get can be used for getting regex value and vars.put can be used for putting it into your variable.