Deal with non existing plural values in Relevance language

Hi there, i’ve a bad day tryng to deal with something like that:

q: (if exist it then “yes” else “no”) of matches (regex “some_regex”) of lines of files “C:\my_file”

if matches return 1 or more results it’s ok, but if returns a nothing (exist = false) then the output of the if “no” will not print.

can anyone help me?
thank in advance.

The parentheses are used to iterate over multiple results (the logic “if exist it then “yes” else “no”” is execute in a loop, repeating over each match; so if there is no match, the parentheses don’t execute.

Instead, try

if exists matches (regex "some_regex") of lines of files "C:\my_file" then "yes" else "no"
or, if you can deal with a boolean result instead, the following will give a True/False instead -
exists matches (regex "some_regex") of lines of files "C:\my_file"

1 Like

I agree with @JasonWalker 's answer, and it is what I would recommend. The following is more about relevance error suppression and some alternative options, but the extra complexity isn’t warranted.


There is some even weirder versions used to suppress errors.

Q: exists true whose (if true then THIS_IS_INVALID else false)
A: False
T: 0.104 ms
I: singular boolean

Q: (if it then "yes" else "no") of ( exists true whose (if true then ( exists matches (regex "some_regex") of lines of files "C:\my_file" ) else false) )
A: no
T: 0.174 ms
I: singular string

This basically forces a TRUE or FALSE result.

It works because of this:

Q: exists TRUE whose(FALSE)
A: False
T: 0.028 ms
I: singular boolean

This is actually equivalent:

Q: exists "Blah" whose(FALSE)
A: False
T: 0.029 ms
I: singular boolean

This happens because the literal value of "Blah" is only returned if the whose statement is true, otherwise it returns NULL / DoesNotExist :

Q: "Blah" whose(FALSE)
E: Singular expression refers to nonexistent object.

This means the following should work:

Q: "yes" whose(FALSE) | "no"
A: no
T: 0.032 ms
I: singular string

Q: "yes" whose(TRUE) | "no"
A: yes
T: 0.030 ms
I: singular string

This shorthand version wasn’t possible until the | operator was added.

2 Likes

mhm yes i’ve noticed that this works, but i need to do something with “it” if exist, for example:

(if exist it then ("yes" & it) else "no") of matches (regex "some_regex") of lines of files "C:\my_file"

1 Like

I’m confused. Do you mean you need to do something other than return “yes” or “no”?

Both @JasonWalker 's and my answers will work given the initial parameters of the question.

What is the final result? or what are you needing to do subsequently? In what way do our answers not work for you? What do you need to do with “it”?

You need to give us more info to answer the question better, because as far as I can tell we already have.


Try this:

(if it then "yes" else "no") of (exists matches (regex "some_regex") of lines of files "C:\my_file")

Or this:

"yes" whose(exists matches (regex "some_regex") of lines of files "C:\my_file") | "no"

If these don’t work, please let us know how so.

1 Like

You’re right, my initial answer was solved, anyway for completeness i need to print the value of “it” if it exist, maybe concatenated with the origin file pathname, “No match” otherwise.

This piece of code is nested so i thoght to use it to not write something like that:

if (exists matches (regex "some_regex") of lines of files "C:\my_file") then (matches (regex "some_regex") of lines of files "C:\my_file") else "No match"

1 Like

If you just do this:

Then if there is no match, then the console will report it as <none>

Why isn’t that sufficient?

Also, one advantage of this method is that the console will sort all of the <none> results in a special way instead of mixing them into the results.

If you instead return No Match then you will get results sorted like: A, B, C, No Match, P, Q, Z

If you use the IF/THEN/ELSE statement like you propose, then you end up doing the regex twice, which is less efficient.

1 Like

Another note on optimization. It is likely faster to only perform the regex on lines that may contain the useful data that the regex is going to extract rather than all lines of the file.

For instance, if you are extracting email addresses from the lines of the file, then it may be faster to do this:

matches (regex "some_regex") of lines containing "@" of files "C:\my_file"

I don’t know what the exact regex is that you are using, but if you can share it, it would be useful.

One problem with regex in general is that it is possible for it to take a longer time depending on the input provided to it and writing a regex to handle all possible cases well is hard and can often make it overly complicated. You can use relevance to only hand over a narrow scope of possible inputs to then be able to run a much more simplified regex against, and in many cases, you don’t need to use regex at all.