for example,
fun f #"a"::_ = "first character is a"
But this does not work in sml.
Is there anyway I can do pattern matching on string without turning it to a char list?
Your code doesn't work because you forget to include the bracket, so it should be something like this:
fun f (#"a"::_) = "first character is a";
If you want to do a pattern matching on string, you can use substring directly. In this case, it can be:
fun f (str) = if substring(str, 0, 1) = "a" then "first character is a" else ""
Related
I need to write a function that takes a string as input. This function will return a List[String]. I have to use the regular expression "\w+" in this function as a requirement for this task. So when given a line string of random text with a few actual words dotted around inside it, I need to add all of these 'proper' words and add them to the list to be returned. I must also use ".findAllIn". I have tried the following
def foo(stringIn: String) : List[String] = {
val regEx = """\w+""".r
val match = regEx.findAllIn(s).toList
match
}
But it just returns the string that I pass into the function.
match is a reserved keyword in scala. So you just need to replace that.
def foo(stringIn: String) : List[String] = {
val regEx = """\w+""".r
regEx.findAllIn(stringIn).toList
}
scala> foo("hey. how are you?")
res17: List[String] = List(hey, how, are, you)
\\w is the pattern for a word character, in the current regex context equal to [a-zA-Z_0-9], that matches a lower- and uppercase letters, digits and an underscore.
\\w+ is for one ore more occurrences of the above.
scala> foo("hey")
res18: List[String] = List(hey)
In above case, there is nothing for the regex to split by. Hence returns the original string.
scala> foo("hey-hey")
res20: List[String] = List(hey, hey)
- is not part of \\w. Hence it splits by -
I have two list of Strings. Now I want to replace every occurence of a word in the first list at index i with a word in the second list at index i of a sentence.
So if I have
list a=("am","I","my")
and
list b=("are","You","your")
I want the sentence "I am an amateur"
to become "You are an amateur"
What is cleanest way to do that in Kotlin (without for loop)?
First split the string to a list of its words and then map each word if it exists in list a to the corresponding word in list b. Finally rejoin the string:
val a= listOf("am","I","my")
val b= listOf("are","You","your")
val str = "I am an amateur"
val new = str
.split("\\s+".toRegex())
.map { val i = a.indexOf(it); if (i < 0) it else b[i] }
.joinToString(" ")
Another way of doing the same thing is:
var new = " $str "
a.forEachIndexed { i, s -> new = new.replace(" $s ", " ${b[i]} ") }
new = new.trim()
although this is closer to a for loop.
I assume there is no punctuation, all whitespaces are spaces and so on.
val m = a.zip(b).toMap()
return s.split(' ').joinToString(" ") { m[it] ?: it }
First you create a map m for more efficient... mapping. Then
Split the string to get a list of words
Map all words: if m contains the word, then return the value (i.e. the replacement), otherwise return the original word (since we shouldn't replace it).
Join all words, separate them by spaces.
You can use the regular expression \b\w+\b to match words in a sentence and then call replace function with the lambda that provides a replacement string for each match:
val input = "I am an amateur, alas."
val wordsToReplace = listOf("I", "am", "my")
val wordsReplaceWith = listOf("You", "are", "your")
val wordRegex = """\b\w+\b""".toRegex()
val result = wordRegex.replace(input) { match ->
val wordIndex = wordsToReplace.indexOf(match.value)
if (wordIndex >= 0) wordsReplaceWith[wordIndex] else match.value
}
println(result)
If there are a lot of word in your lists, it makes sense to build a map of them to speed up searches:
val replaceMap = (wordsToReplace zip wordsReplaceWith).toMap()
val result = wordRegex.replace(input) { match ->
replaceMap[match.value] ?: match.value
}
I think the simplest way is to create a set of regex you want and replace the string by iteration. Let's say you want to replace the word "am", your regex will be "\bam\b". You can use "(?i)\bam\b" if you want it not to be case sensitive. To make "I am an amateur" to "You are an amateur"
val replacements = setOf("\\bam\\b" to "are",
"\\bI\\b" to "You",
"\\bmy\\b" to "your")
replacements.forEach {
str = str.replace(Regex(it.first), it.second)
}
I have a str value containing a fair amount of text, and I match it against a regex. The str contains multiple matches of the regex, but of course I only get the first.
How can I enumerate over the other matches, of better, how can I collect them into a list[str] ?
Example:
str text = "hello here how home";
Now I can do:
if (/<match:h+>/ := text) println(match);
which prints the first match: hello.
Now, instead, I'd love to collect all matches into a list[str]. Other languages provide the g flag for global matching. What's Rascal's idiom for this?
In general you can iterate over a pattern until there are no new matches to be made.
for (/<match:h+>/ := "hello here how home") {
println(h);
}
or
[ h | /<match:h+>/ := "hello here how home"]
the reverse is also true, if you want to know if there is at least one item in a list:
if (_ <- lst) {
println("lst is not empty");
}
Read more on Pattern Matching and Enumerators in the tutor.
If you want to match the word you might have to change the regex: /<word:h\w+>/
I want to replace all the consecutive underscores with a single space. This is the code that I have written. But it is not replacing anything. Below is the code that I have written. What am I doing wrong?
import scala.util.matching.Regex
val regex: Regex = new Regex("/[\\W_]+/g")
val name: String = "cust_id"
val newName: String = regex.replaceAllIn(name, " ")
println(newName)
Answer: "cust_id"
You could use replaceAll to do the job without regex :
val name: String = "cust_id"
val newName: String = name.replaceAll("_"," ")
println(newName)
The slashes in your regular expression don't belong there.
new Regex("[\\W_]+", "g").replaceAllIn("cust_id", " ")
// "cust id"
A string in Scala may be treated as a collection, hence we can map over it and in this case apply pattern matching to substitute characters, like this
"cust_id".map {
case '_' => " "
case c => c
}.mkString
Method mkString glues up the vector of characters back onto a string.
I need to determine whether a string begins with a number - I've tried the following to no avail:
if (matches("^[0-9].*)", upper(text))) str = "Title"""
I'm new to DXL and Regex - what am I doing wrong?
You need the caret character to indicate a match only at the start of a string. I added the plus character to match all the numbers, although you might not need it for your situation. If you're only looking for numbers at the start, and don't care if there is anything following, you don't need anymore.
string str1 = "123abc"
string str2 = "abc123"
string strgx = "^[0-9]+"
Regexp rgx = regexp2(strgx)
if(rgx(str1)) { print str1[match 0] "\n" } else { print "no match\n" }
if(rgx(str2)) { print str2[match 0] "\n" } else { print "no match\n" }
The code block above will print:
123
no match
#mrhobo is correct, you want something like this:
Regexp numReg = "^[0-9]"
if(numReg text) str = "Title"
You don't need upper since you are just looking for numbers. Also matches is more for finding the part of the string that matches the expression. If you just want to check that the string as a whole matches the expression then the code above would be more efficient.
Good luck!
At least from example I found this example should work:
Regexp plural = regexp "^([0-9].*)$"
if plural "15systems" then print "yes"
Resource:
http://www.scenarioplus.org.uk/papers/dxl_regexp/dxl_regexp.htm