In scala ,I have a string where I need to replace %23 with # , as below:
From https://bucket_name.s3.amazonaws.com/scripts/%23%23%23ENVIRONMENT_NAME%23%23%23/abc/template_abc_windows_%23%23%23ENVIRONMENT_NAME%23%23%23.zip?X-Amz-Security-Token=FQoGZXIvYXdzEOghsfgdghgkjkjjklj
to https://bucket_name.s3.amazonaws.com/scripts/###ENVIRONMENT_NAME###/abc/template_abc_windows_###ENVIRONMENT_NAME###.zip?X-Amz-Security-Token=FQoGZXIvYXdzEOghsfgdghgkjkjjklj
I have used below regex and logic for substitution but I get error as:
java.lang.IllegalStateException: No match found
Code:
val originalURL = "https://bucket_name.s3.amazonaws.com/scripts/%23%23%23ENVIRONMENT_NAME%23%23%23/abc/template_abc_windows_%23%23%23ENVIRONMENT_NAME%23%23%23.zip?X-Amz-Security-Token=FQoGZXIvYXdzEOghsfgdghgkjkjjklj"
val pattern = Pattern.compile("(https://bucket_name.s3.amazonaws.com/scripts/)((%23){3})([a-zA-Z]+_[a-zA-Z]+)((%23){3})(/abc/template_abc_windows_)((%23){3})([a-zA-Z]+_[a-zA-Z]+)((%23){3})(..*)")
val matcher = pattern.matcher(originalURL)
val replacedURL = matcher.group(1)+"###"+ matcher.group(4)+"###"+ matcher.group(7)+"###"+ matcher.group(10)+"###"+matcher.group(13)
println("*******replacedURL******* => "+ replacedURL)
Any help is much appreciated.Thank you.
Maybe you can just use String.replaceAll?
val url = "https://bucket_name.s3.amazonaws.com/scripts/%23%23%23ENVIRONMENT_NAME%23%23%23/abc/template_abc_windows_%23%23%23ENVIRONMENT_NAME%23%23%23.zip?X-Amz-Security-Token=FQoGZXIvYXdzEOghsfgdghgkjkjjklj"
url.replaceAll("%23", "#")
Related
I have the following input string: val s = 19860803 000000
I want to convert it to 1986/08/03
I tried this s.split(" ").head, but this is not complete
is there any elegant scala coding way with regex to get the expected result ?
You can use a date like pattern using 3 capture groups, and match the following space and the 6 digits.
In the replacement use the 3 groups in the replacement with the forward slashes.
val s = "19860803 000000"
val result = s.replaceAll("^(\\d{4})(\\d{2})(\\d{2})\\h\\d{6}$", "$1/$2/$3")
Output
result: String = 1986/08/03
i haven't tested this, but i think the following will work
val expr = raw"(\d{4})(\d{2})(\d{2}) (.*)".r
val formatted = "19860803 000000" match {
case expr(year,month,day,_) =>. s"$year/$month/$day"
}
scala docs have a lot of good info
https://www.scala-lang.org/api/2.13.6/scala/util/matching/Regex.html
An alternative, without a regular expression, by using slice and take.
val s = "19860803 000000"
val year = s.take(4)
val month = s.slice(4,6)
val day = s.slice(6,8)
val result = s"$year/$month/$day"
Or as a one liner
val result = Seq(s.take(4), s.slice(4,6), s.slice(6,8)).mkString("/")
I have below urls in my applications, I want to take one of the value in urls.
For example:
rapidvie value 416
Input URL: http://localhost:8080/bladdey/shop/?rapidView=416&projectKey=DSCI&view=detail&
Output should be: 416
I've written the code in scala using import java.util.regex.{Matcher, Pattern}
val p: Pattern = Pattern.compile("[?&]rapidView=(\\d+)[?&]")**strong text**
val m:Matcher = p.matcher(url)
if(m.find())
println(m.group(1))
I am getting output, but i want to migrate this scala using scala.util.matching library.
How to implement this in simply?
This code is working with java utils.
In Scala, you may use an unanchored regex within a match block to get just the captured part:
val s = "http://localhost:8080/bladdey/shop/?rapidView=416&projectKey=DSCI&view=detail&"
val pattern ="""[?&]rapidView=(\d+)""".r.unanchored
val res = s match {
case pattern(rapidView) => rapidView
case _ => ""
}
println(res)
// => 416
See the Scala demo
Details:
"""[?&]rapidView=(\d+)""".r.unanchored - the triple quoted string literal allows using single backslashes with regex escapes, and the .unanchored property makes the regex match partially, not the entire string
pattern(rapidView) gets the 1 or more digits part (captured with (\d+)) if a pattern finds a partial match
case _ => "" will return an empty string upon no match.
You can do this quite easily with Scala:
scala> val url = "http://localhost:8080/bladdey/shop/?rapidView=416&projectKey=DSCI&view=detail&"
url: String = http://localhost:8080/bladdey/shop/?rapidView=416&projectKey=DSCI&view=detail&
scala> url.split("rapidView=").tail.head.split("&").head
res0: String = 416
You can also extend it by parameterize the search word:
scala> def searchParam(sp: String) = sp + "="
searchParam: (sp: String)String
scala> val sw = "rapidView"
sw: String = rapidView
And just search with the parameter name
scala> url.split(searchParam(sw)).tail.head.split("&").head
res1: String = 416
scala> val sw2 = "projectKey"
sw2: String = projectKey
scala> url.split(searchParam(sw2)).tail.head.split("&").head
res2: String = DSCI
I am struggling with regexps in Scala (2.11.5), I have a followin string to parse (example):
val string = "http://sth.com/sth/56,57597,14058913,Article_title,,5.html"
I want to extract third numeric value in the string above (it needs to be third after a slash because there can be other groups following), in order to do that I have the following regex pattern:
val pattern = """\/\d+,\d+,(\d+)""".r
I have been trying to retrieve the group for the third sequence of digits, but nothing seems to work for me.
val matchList = pattern.findAllMatchIn(string).foreach(println)
val matchListb = pattern.findAllIn(string).foreach(println)
I also tried using matching pattern.
string match {
case pattern(a) => println(a)
case _ => "What's going on?"
}
and got the same results. Either whole regexp is returned or nothing.
Is there an easy way to retrieve a group form regexp pattern in Scala?
You can use group method of scala.util.matching.Regex.Match to get the result.
val string = "http://sth.com/sth/56,57597,14058913,Article_title,,5.html"
val pattern = """\/\d+,\d+,(\d+)""".r
val result = pattern.findAllMatchIn(string) // returns iterator of Match
.toArray
.headOption // returns None if match fails
.map(_.group(1)) // select first regex group
// or simply
val result = pattern.findFirstMatchIn(string).map(_.group(1))
// result = Some(14058913)
// result will be None if the string does not match the pattern.
// if you have more than one groups, for instance:
// val pattern = """\/(\d+),\d+,(\d+)""".r
// result will be Some(56)
Pattern matching is usually the easiest way to do it, but it requires a match on the full string, so you'll have to prefix and suffix your regex pattern with .*:
val string = "http://sth.com/sth/56,57597,14058913,Article_title,,5.html"
val pattern = """.*\/\d+,\d+,(\d+).*""".r
val pattern(x) = string
// x: String = 14058913
Could you guys please tell me what I'm doing incorrectly trying to extract using regex pattern-matching? I have following code
val Pattern = "=".r
val Pattern(key, value) = "key=value"
And I get following exception in runtime
Exception in thread "main" scala.MatchError: key=value (of class java.lang.String)
That's more of a regular expression problem: your regex does not capture any groups, it just matches a single = character.
With
val Pattern = "([^=]*)=(.*)".r
you will get:
scala> val Pattern(key, value) = "key=value"
key: String = key
value: String = value
Edit:
Also, that won't match if the input string is empty. You can change the pattern to make it match, or (better) you can pattern match with the regex, like so:
"key=value" match {
case Pattern(k, v) => // do something
case _ => // wrong input, do nothing
}
If what you actually wanted was to split the input text with whatever the regex matches, that is also possible using Regex.split:
scala> val Pattern = "=".r
Pattern: scala.util.matching.Regex = =
scala> val Array(key, value) = Pattern.split("key=value")
key: String = key
value: String = value
Let's say I have this code:
val string = "one493two483three"
val pattern = """two(\d+)three""".r
pattern.findAllIn(string).foreach(println)
I expected findAllIn to only return 483, but instead, it returned two483three. I know I could use unapply to extract only that part, but I'd have to have a pattern for the entire string, something like:
val pattern = """one.*two(\d+)three""".r
val pattern(aMatch) = string
println(aMatch) // prints 483
Is there another way of achieving this, without using the classes from java.util directly, and without using unapply?
Here's an example of how you can access group(1) of each match:
val string = "one493two483three"
val pattern = """two(\d+)three""".r
pattern.findAllIn(string).matchData foreach {
m => println(m.group(1))
}
This prints "483" (as seen on ideone.com).
The lookaround option
Depending on the complexity of the pattern, you can also use lookarounds to only match the portion you want. It'll look something like this:
val string = "one493two483three"
val pattern = """(?<=two)\d+(?=three)""".r
pattern.findAllIn(string).foreach(println)
The above also prints "483" (as seen on ideone.com).
References
regular-expressions.info/Lookarounds
val string = "one493two483three"
val pattern = """.*two(\d+)three.*""".r
string match {
case pattern(a483) => println(a483) //matched group(1) assigned to variable a483
case _ => // no match
}
Starting Scala 2.13, as an alternative to regex solutions, it's also possible to pattern match a String by unapplying a string interpolator:
"one493two483three" match { case s"${x}two${y}three" => y }
// String = "483"
Or even:
val s"${x}two${y}three" = "one493two483three"
// x: String = one493
// y: String = 483
If you expect non matching input, you can add a default pattern guard:
"one493deux483three" match {
case s"${x}two${y}three" => y
case _ => "no match"
}
// String = "no match"
You want to look at group(1), you're currently looking at group(0), which is "the entire matched string".
See this regex tutorial.
def extractFileNameFromHttpFilePathExpression(expr: String) = {
//define regex
val regex = "http4.*\\/(\\w+.(xlsx|xls|zip))$".r
// findFirstMatchIn/findAllMatchIn returns Option[Match] and Match has methods to access capture groups.
regex.findFirstMatchIn(expr) match {
case Some(i) => i.group(1)
case None => "regex_error"
}
}
extractFileNameFromHttpFilePathExpression(
"http4://testing.bbmkl.com/document/sth1234.zip")