String includes many substrings in ScalaTest Matchers - string

I need to check that one string contains many substrings. The following works
string should include ("seven")
string should include ("eight")
string should include ("nine")
but it takes three almost duplicated lines. I'm looking for something like
string should contain allOf ("seven", "eight", "nine")
however this doesn't work... The assertion just fails while string contains these substrings for sure.
How can I perform such assertion in one line?

Try this:
string should (include("seven") and include("eight") and include("nine"))

You can always create a custom matcher:
it should "..." in {
"str asd dsa ddsd" should includeAllOf ("r as", "asd", "dd")
}
def includeAllOf(expectedSubstrings: String*): Matcher[String] =
new Matcher[String] {
def apply(left: String): MatchResult =
MatchResult(expectedSubstrings forall left.contains,
s"""String "$left" did not include all of those substrings: ${expectedSubstrings.map(s => s""""$s"""").mkString(", ")}""",
s"""String "$left" contained all of those substrings: ${expectedSubstrings.map(s => s""""$s"""").mkString(", ")}""")
}
See http://www.scalatest.org/user_guide/using_matchers#usingCustomMatchers for more details.

Related

Flutter - How to replace text (containing "id") with title for the id?

I have text like this:
Forecaster Strongly disagree \n\nSomething else is going to happen\n\nExample:-\n\n#:hashtag/424 \n#:hashtag/2818 ",
I need to get 424 and 2818 (which are ids) and find titles for those ids and replace #:hashtag/424 with #Title1
How do I manipulate string for this?
You can use a regular expression like this:
RegExp exp = RegExp(r'#:hashtag\/(\d+)');
String test = "Forecaster Strongly disagree \n\nSomething else is going to happen\n\nExample:-\n\n#:hashtag/424 \n#:hashtag/2818";
final matches = exp.allMatches(test);
if(matches.isNotEmpty){
print (matches.first[0]!.split('/').last);
}
//prints 424
some additional null checks will probably be nececssary depending on what you can expect from the input string
To replace the IDs you could use the replaceAllMapped method like this:
test.replaceAllMapped(exp, (match) => match[0]!.split('/').first + '/#Title1');

How to check if a String contains multiple values and ignore case with StringUtils

I wrote a method to check if a string contains various values.
def validateString(metricValue: String): Boolean = {
(!StringUtils.containsIgnoreCase(metricValue, "metric_1")
&& StringUtils.containsIgnoreCase(metricValue, "metric_2")
|| StringUtils.containsIgnoreCase(metricValue, "metric_3")
}
Then I decided to reduce the last two checks to a single one but haven't found anything that may be helpful in commons-lang-2.6.
I know there is a similar method in lang 3: StringUtils.equalsAnyIgnoreCase(str, "val1", "val2", "val3")). But I need something like containsAnyIgnoreCase.
Is there a way to check if any of multiple values is present in a String ignoring the case?
Try
List("metric_2", "metric_3")
.map(_.toLowerCase)
.contains(metricValue.toLowerCase)
If you want to use StringUtils:
def validateString(metricValue: String): Boolean =
List("metric_2", "metric_3").exists(metricToCheck => StringUtils.containsIgnoreCase(metricValue, metricToCheck))

How to check if string contains a substring in terraform interpolation?

How do you check if a terraform string contains another string?
For example, I want to treat terraform workspaces with "tmp" in the name specially (e.g. allowing rds instances to be deleted without a snapshot), so something like this:
locals
{
is_tmp = "${"tmp" in terraform.workspace}"
}
As far as I can tell, the substr interpolation function doesn't accomplish this.
For terraform 0.12.xx apparently you are suppose to use regexall to do this.
From the manual for terraform 0.12.XX:
regexall() documentation
regexall can also be used to test whether a particular string matches a given pattern, by testing whether the length of the resulting list of matches is greater than zero.
Example from the manual:
> length(regexall("[a-z]+", "1234abcd5678efgh9"))
2
> length(regexall("[a-z]+", "123456789")) > 0
false
Example applied to your case in terraform 0.12.xx syntax should be something like:
locals
{
is_tmp = length(regexall(".*tmp.*", terraform.workspace)) > 0
}
It also specifically says in the manual not to use "regex" but instead use regexall.
If the given pattern does not match at all, the regex raises an error. To test whether a given pattern matches a string, use regexall and test that the result has length greater than zero.
As stated above this is because you will actually get an exception error when you try to use it in the later versions of 0.12.xx that are out now when you run plan. This is how I found this out and why I posted the new answer back here.
You can indirectly check for substrings using replace, e.g.
locals
{
is_tmp = "${replace(terraform.workspace, "tmp", "") != terraform.workspace}"
}
Like #MechaStorm, with Terrafor 0.12.7+ you can use regex to return a Boolean value if your string contains a particular substring
locals {
is_tmp = contains(regex("^(?:.*(tmp))?.*$",terraform.workspace),"tmp")
}
The regex query returns a list of capture groups for any characters before tmp, tmp if found, any characters after tmp. Then contains looks for "tmp" in the list and returns true or false. I am using this type of logic in my own terraform.
Length of the list produced by split function is greater than one when separtor is a substring.
locals {
is_tmp = length(split("tmp", terraform.workspace)) > 1
}
Use replace( string, search, replace ) as in the snippet:
// string contains ABBA = result is ABBA
output "match" {
value = "${ replace("xxxABBAyyy", "/(?:.*)(ABBA)(?:.*)/", "$1") }"
}
// string doesn't contain ABBA = result is original string
output "no_match" {
value = "${ replace("xxxBABAyyy", "/(?:.*)(ABBA)(?:.*)/", "$1")}"
}
// string contains ABBA (ingorecase) = result is AbBA
output "equals_ignorecase" {
value = "${ replace("xxxAbBAyyy", "/(?:.*)((?i)ABBA)(?:.*)/", "$1")}"
}
An output of terraform apply is:
Outputs:
equals_ignorecase = AbBA
match = ABBA
no_match = xxxBABAyyy
In terraform 0.12.7, we now have regex . This may help simplify some code and make it readable to some (perhaps?)
> regex("[a-z]+", "53453453.345345aaabbbccc23454")
aaabbbccc
I use this way to check if bucket name start with test-tmp
eg. test-tmp, test-tmp-app1, test-tmp-db1 etc..
is_test_bucket = can(regex("^(test-tmp){1}($|-{1}.*$)", var.bucket_name))
Something that makes sense reading, IMHO:
locals {
is_tmp = can(regex("tmp", terraform.workspace))
}
This works because the regex function will raise an error if no matches are found.
Bonus: since Terraform 1.3.x, there are the new startswith and endswith functions that can be handy in a good amount of cases.

Scala: split string via pattern matching

Is it possible to split string into lexems somehow like
"user#domain.com" match {
case name :: "#" :: domain :: "." :: zone => doSmth(name, domain, zone)
}
In other words, on the same manner as lists...
Yes, you can do this with Scala's Regex functionality.
I found an email regex on this site, feel free to use another one if this doesn't suit you:
[-0-9a-zA-Z.+_]+#[-0-9a-zA-Z.+_]+\.[a-zA-Z]{2,4}
The first thing we have to do is add parentheses around groups:
([-0-9a-zA-Z.+_]+)#([-0-9a-zA-Z.+_]+)\.([a-zA-Z]{2,4})
With this we have three groups: the part before the #, between # and ., and finally the TLD.
Now we can create a Scala regex from it and then use Scala's pattern matching unapply to get the groups from the Regex bound to variables:
val Email = """([-0-9a-zA-Z.+_]+)#([-0-9a-zA-Z.+_]+)\.([a-zA-Z]{2,4})""".r
Email: scala.util.matching.Regex = ([-0-9a-zA-Z.+_]+)#([-0-9a-zA-Z.+_]+)\.([a-zA-Z] {2,4})
"user#domain.com" match {
case Email(name, domain, zone) =>
println(name)
println(domain)
println(zone)
}
// user
// domain
// com
Starting Scala 2.13, it's possible to pattern match a Strings by unapplying a string interpolator:
val s"$user#$domain.$zone" = "user#domain.com"
// user: String = "user"
// domain: String = "domain"
// zone: String = "com"
If you are expecting malformed inputs, you can also use a match statement:
"user#domain.com" match {
case s"$user#$domain.$zone" => Some(user, domain, zone)
case _ => None
}
// Option[(String, String, String)] = Some(("user", "domain", "com"))
In general regex is horribly inefficient, so wouldn't advise.
You CAN do it using Scala pattern matching by calling .toList on your string to turn it into List[Char]. Then your parts name, domain and zone will also be List[Char], to turn them back into Strings use .mkString. Though I'm not sure how efficient this is.
I have benchmarked using basic string operations (like substring, indexOf, etc) for various use cases vs regex and regex is usually an order or two slower. And of course regex is hideously unreadible.
UPDATE: The best thing to do is to use Parsers, either the native Scala ones, or Parboiled2

Lua: How to get string captures containing a specific substring?

In Lua, in want to get captures from a string containing a specific substring. E.g. in the string
test = "<item>foo</item> <item>bar</item>"
I want to get items containing "a", which in this case would be "bar". I tried this:
print(string.find(test, "<item>(.-a.-)</item>"))
but the result is:
1 34 foo</item> <item>bar
So .- is more greedy than I expected. What would be the correct pattern?
Try print(string.find(test, "<item>([^<]-a.-)</item>")).

Resources