I have an array:
#available_languages = ["English", "German", "Japanese"]
and a variable:
#needed_language = "Basic English"
I want to show 'Available!' in the view if a #needed_language is present in the #available_languages array, even if the names don't match exactly, such as 'English' and 'Basic English'
Right now, my conditional only returns true for exact matches. How do I return true for non-exact matches?
- if #available_languages.map{|a| a.available_language_name}.include? #needed_language.needed_language_name
Available!
- else
Not Available
You could use select function, something like this:
#available_languages = ["English", "German", "Japanese"]
#needed_language = "Basic English"
if #needed_language.split(" ").select{ |a| a if #available_languages.include? a} then
"Available"
else
"Not Available"
endif
Related
I have the following string to parse:
X4IitemX6Nabc123
that is structured as follows:
X... marker for 'field identifier'
4... length of item (name), will change according to length of item name
I... identifier for item name, must not be extracted, fixed
item... value that should be extraced as "name"
X... marker for 'field identifier'
6... length of item (name), will change according to length of item name
N... identifier for item number, must not be extracted, fixed
abc123... value that should be extraced as "num"
Only these two values will be contained in the string, the sequence is also always the same (name, nmuber).
What I have so far is
\AX(?I<namelen>\d+)U(?<name>.+)X(?<numlen>\d+)N(?<num>.+)$
But that does not take into account that the length of the name is contained in the string itself. Somehow the .+ in the name group should be replaced by .{4}. I tried {$1}, {${namlen}} but that does not yield the result I expect (on rubular.com or regex.191)
Any ideas or further references?
What you ask for is only possible in languages that allow code insertions in the regex pattern.
Here is a Perl example:
#!/usr/bin/perl
use warnings;
use strict;
my $text = "X4IitemX6Nabc123";
if ($text =~ m/^X(?<namelen>[0-9]+)I(?<name>(??{".{".$^N."}"}))X(?<numlen>[0-9]+)N(?<num>.+)$/) {
print $text . ": PASS!\n";
} else {
print $text . ": FAIL!\n"
}
# -> X4IitemX6Nabc123: PASS!
In other languages, use a two-step approach:
Extract the number after X,
Build a regex dynamically using the result of the first step.
See a JavaScript example:
const text = "X4IitemX6Nabc123";
const rx1 = /^X(\d+)/;
const m1 = rx1.exec(text)
if (m1) {
const rx2 = new RegExp(`^X(?<namelen>\\d+)I(?<name>.{${m1[1]}})X(?<numlen>\\d+)N(?<num>.+)$`)
if (rx2.test(text)) {
console.log(text, '-> MATCH!')
} else console.log(text, '-> FAIL!');
} else {
console.log(text, '-> FAIL!')
}
See the Python demo:
import re
text = "X4IitemX6Nabc123"
rx1 = r'^X(\d+)'
m1 = re.search(rx1, text)
if m1:
rx2 = fr'^X(?P<namelen>\d+)I(?P<name>.{{{m1.group(1)}}})X(?P<numlen>\d+)N(?P<num>.+)$'
if re.search(rx2, text):
print(text, '-> MATCH!')
else:
print(text, '-> FAIL!')
else:
print(text, '-> FAIL!')
# => X4IitemX6Nabc123 -> MATCH!
How this m Power BI M code can be modified
= Table.AddColumn(#"PreviousStep", "Tag", each
if Text.Contains([Column1]) = "value1" then "bingo"
else if Text.Contains([Column1]) = "value2" then "bingo"
else if Text.Contains([Column1]) = "value3" then "bingo"
else ["Some other value"])
into a one line code similar to SQL
case when [Column1] in ("value1", "value2", "value3") then "bingo" else "Some other value" end
I would not like to repeat the lines else if but have it in a similar way as
List.Contains({'Value1', 'Value2', 'Value3'}, [Column1])
used here: https://stackoverflow.com/a/51749519/1903793
If you want to compare whole word, you should use List.ContainsAny function
let
haystack = #table({"col"}, {{"qwer"}, {"asdf"}, {"zxcv"}, {"zxwecv"}, {"other"}}),
needles = {"qwer", "zxcv"},
add = Table.AddColumn(haystack, "Tag", each if List.ContainsAny(needles, {[col]}) then "bingo" else "Some other value")
in
add
But if you search a part of word, the answer becomes a little more complicated
let
haystack = #table({"col"}, {{"qwer"}, {"asdf"}, {"zxcv"}, {"zxwecv"}, {"other"}}),
needles = {"we", "as"},
add = Table.AddColumn(haystack, "Tag", each if List.MatchesAny(needles, (s)=>Text.Contains([col], s)) then "bingo" else "Some other value")
in
add
Or if you want to return the string that matches, you can use the List.Accumulate function:
List.Accumulate(YOUR_LIST_OF_STRINGS, null, (state, current) => if Text.Contains([YOUR COLUMN NAME], current) then current else state)
The only disadvantage to this method is that if there are multiple matches it will return only the last...
Here's a more complex version that returns a list of the matched strings:
List.Accumulate(YOUR_LIST_OF_STRINGS, {}, (state, current) => if Text.Contains([YOUR COLUMN NAME], current) then List.Combine({{current}, state}) else state)
Or you could amend that so that it returns a comma delimited list as a string etc., or whatever.
You have to use List.Transform to generate the Text.Contains function call, then use List.AnyTrue to check if Column1 contains any of the text.
= Table.AddColumn(#"PreviousStep", "Tag", each if List.AnyTrue(List.Transform({"value1", "value2", "value3"}, (s) => Text.Contains([Column1], (s)))) then "bingo" else "Some other value")
Results:
Reference
I know next to nothing about regular expressions and after reading tutorials on several sites, still know next to nothing. I want a regular expression that will validate/enforce that a film rating is one of G, PG-13, R or NC-17.
You didn't specify the programming language you're using, but you don't need a regex, i.e.:
for python:
ratings = ['G','PG-13','R','NC-17']
rating = "PG-13"
if rating in ratings:
print "ranking exist"
else:
print "no match"
for php:
$ratings = array('G','PG-13','R','NC-17');
$rating = 'PG-13';
if (in_array($rating, $ratings))
{
print "rating exist";
} else {
print "no match";
}
So, as part of learning the language, I wanted to check three strings for a certain pattern and return the first match of that pattern only.
My attempt was to use a combination of find and regular expressions to traverse the list:
def date = [
"some string",
"some other string 11.11.2000",
"another one 20.10.1990"
].find { title ->
title =~ /\d{2}\.\d{2}\.\d{4}/
}
This kind of works, leaving the whole string in date.
My goal, however, would be to end up with "11.11.2000" in date; I assume somehow I should be able to access the capture group, but how?
If you want to return a specific value when finding a matching element in a collection (which as in your case might be part of that element), you need to use findResult.
Your code might then look like this
def date = [
"some string",
"some other string 11.11.2000",
"another one 20.10.1990"
].findResult { title ->
def res = title =~ /\d{2}\.\d{2}\.\d{4}/
if (res) {
return res[0]
}
}
Extending UnholySheep's answer, you can also do this:
assert [
"some string",
"some other string 11.11.2000",
"another one 20.10.1990"
].findResult { title ->
def matcher = title =~ /\d{2}\.\d{2}\.\d{4}/
matcher.find() ? matcher.group() : null
} == '11.11.2000'
For all matches, just use findResults instead of findResult, like this:
assert [
"some string",
"some other string 11.11.2000",
"another one 20.10.1990"
].findResults { title ->
def matcher = title =~ /\d{2}\.\d{2}\.\d{4}/
matcher.find() ? matcher.group() : null
} == ['11.11.2000', '20.10.1990']
Im trying to replace one part of my string using a dict.
s = 'I am a string replaceme'
d = {
'replaceme': 'replace me'
}
Ive tried lots of variations like
s = s.replace(d, d[other])
That throws an error being name error: name 'other' is not defined. If I do
s = s.replace('replaceme', 'replace me')
It works. How can i achive my goal?
You have to replace each KEY of your dict with the VALUE associated. Which value holds the other variable? Is it a valid KEY of your substitutions dict?
You can try with this solution.
for k in d:
s = s.replace(k, d[k])
Each key in dictionary is the value to be replaced, using the corresponding VALUE accessed with d[k].
If the dictionary is big the provided example will show poor performances.
You could split the string and rejoin:
s = 'I am a string replaceme'
d = {
'replaceme': 'replace me'
}
print(" ".join([w if w not in d else d[w] for w in s.split(" ")]))
That won't match substrings where str.replace will, if you are trying to match substring iterate over the dict.items and replace the key with the value:
d = {
'replaceme': 'replace me'
}
for k,v in d.items():
s = s.replace(k,v)
print(s)
I am a string replace me
Here is a different approach: using reduce:
s = 'I am a string replaceme'
d = {'replaceme': 'replace me', 'string': 'phrase,'}
s = reduce(lambda text, old_new_pair: text.replace(* old_new_pair), d.items(), s)
# s is now 'I am a phrase, replace me'