Error on car's license plate regex validation - regex

I'm running the following test to validate a car's license plate. What am I doing wrong?
testInvalid return error
testValid return success
#Test
fun testInvalid() {
val value = "ABC12345"
val pattern = Pattern.compile("[A-Z]{3}[0-9]{4}")
val matcher = pattern.matcher(value)
val found = matcher.find()
System.out.print("$value is valid: $found")
Assert.assertFalse(found)
}
#Test
fun testValid() {
val value = "ABC1234"
val pattern = Pattern.compile("[A-Z]{3}[0-9]{4}")
val matcher = pattern.matcher(value)
val found = matcher.find()
System.out.print("$value is valid: $found")
Assert.assertTrue(found)
}

You need to use the $ character at the end of regEx to indicate the end:
#Test
fun testInvalid() {
val value = "ABC12345"
val pattern = Pattern.compile("[A-Z]{3}[0-9]{4}$")
val matcher = pattern.matcher(value)
val found = matcher.find()
System.out.print("$value is valid: $found")
Assert.assertFalse(found)
}
#Test
fun testValid() {
val value = "ABC1234"
val pattern = Pattern.compile("[A-Z]{3}[0-9]{4}$")
val matcher = pattern.matcher(value)
val found = matcher.find()
System.out.print("$value is valid: $found")
Assert.assertTrue(found)
}

Related

Return list outside ForEach loop return only last item in Kotlin

I need to return all list items, in forEach it works fine, outside the loop it only returns the last item.
fun scanAndConvertFile(): String {
val scanner = Scanner(System.`in`)
print("Enter path to file to convert: ")
val fileName: String = scanner.nextLine()
val bufferedReader: BufferedReader = File(fileName).bufferedReader()
var result = bufferedReader.use { it.readText() }
val header = result.substring(0, result.indexOf(":61:"))
val body = result.substring(result.indexOf(":61:"), result.lastIndexOf(":61:220131C6"))
val footer = result.substring(result.lastIndexOf(":61:220131C6"), result.length)
var list = body.split(":61:")
list = list.filter { it.isNotEmpty() }
list = list.map {
":61:$it"
}
list.forEach() {
val part1 = it.substring(0, it.indexOf("?20"))
var part2ToBePasted = it.substring(it.indexOf("?20"), it.indexOf("?00"))
part2ToBePasted = part2ToBePasted.drop(3)
val part3 = it.substring(it.indexOf("?00"), it.indexOf("?27"))
var part4ToPast = it.substring(it.indexOf("?27"), it.indexOf("?28"))
part4ToPast = part4ToPast.drop(3)
val part5 = it.substring(it.indexOf("?28"), it.length)
list = if(part4ToPast.equals("")) {
listOf(part1.plus("?20").plus(part2ToBePasted).plus(part3).plus("?27").plus(part4ToPast).plus(part5))
} else {
listOf(part1.plus("?20").plus(part4ToPast).plus(part3).plus("?27").plus(part4ToPast).plus(part5))
}
// println(list) - works good
}
val converted = header.plus(list).plus(footer)
// println(converted) - print only last element of list
return converted
}
I tried to clean up your code a little (with no guarantee of course since I do not have any test data):
fun scanAndConvertFile(): String {
print("Enter path to file to convert: ")
val fileName: String = Scanner(System.`in`).nextLine()
val bufferedReader: BufferedReader = File(fileName).bufferedReader()
val result = bufferedReader.use { it.readText() }
val header = result.substring(0, result.indexOf(":61:"))
val footer = result.substring(result.lastIndexOf(":61:220131C6"), result.length)
val list = result
.substring(result.indexOf(":61:"), result.lastIndexOf(":61:220131C6"))
.split(":61:")
.filter { it.isNotEmpty() }
.map { ":61:$it" }
.map {
val indexOf00 = it.indexOf("?00")
val indexOf20 = it.indexOf("?20")
val indexOf27 = it.indexOf("?27")
val indexOf28 = it.indexOf("?28")
val substring27to28 = it.substring(indexOf27, indexOf28).drop(3)
it.substring(0, indexOf20)
.plus("?20")
.plus(if (substring27to28 == "") it.substring(indexOf20, indexOf00).drop(3) else substring27to28)
.plus(it.substring(indexOf00, indexOf27))
.plus("?27")
.plus(substring27to28)
.plus(it.substring(indexOf28, it.length))
}
return header.plus(list).plus(footer)
}
Basically you need to use map instead of forEach to return a list. map is used to transform each element of a list, while with forEach you do something to or with each element, but no list is returned.

When unit testing my ViewModel, list always returns empty

I'm trying to learn unit testing, I have my code factored into an MVVM(i) architecture, but when I run my testParseToList() test function, it always comes back with an empty list and I can't figure out why. I fear it may have something to do with the i part of the MVVM(i) and whether or not I'm correctly mocking my viewmodel. I'm starting with my most simple viewmodel in hopes to get a grasp of the concepts before moving onto my more complex ones.
OfflineViewModelUnitTest.kt
#RunWith(JUnit4::class)
class OfflineViewModelUnitTest {
#get:Rule
val rule = InstantTaskExecutorRule()
#Mock
var offlineViewModel: OfflineViewModel = OfflineViewModel(OfflineInteractorImpl())
#Before
fun setup() {
MockitoAnnotations.initMocks(this)
DaggerOfflineViewModelComponent.builder()
.offlineInteractorImplModule(OfflineInteractorImplModule())
.build()
.inject(offlineViewModel)
// this.offlineViewModel = OfflineViewModel(OfflineInteractorImpl())
}
#Test
fun testParseToList() {
val test = offlineViewModel.parseTextToList("dried bonito extract,\n" +
" ketchup,\n" +
" millet,\n" +
" corn & wheat protein")
val a = "dried bonito extract"
val b = "ketchup"
val c = "millet"
val d = "corn & wheat protein"
val expectedResult = listOf(a, b, c, d)
assertEquals(expectedResult, test)
}
}
OfflineViewModel.kt
class OfflineViewModel(private val offlineInteractor: OfflineInteractor): ViewModel() {
init {
DaggerOfflineViewModelComponent.builder()
.offlineInteractorImplModule(OfflineInteractorImplModule())
.build()
.inject(this)
}
fun parseTextToList(firebaseVisionTextString: String): MutableList<String> {
Log.d("here it is", firebaseVisionTextString)
return offlineInteractor.parseTextToList(firebaseVisionTextString)
}
fun readCsvFromAssetFolder(inputStream: InputStream): List<String>{
return offlineInteractor.readCsvFromAssetFolder(inputStream)
}
}
OfflineInteractorImpl.kt
class OfflineInteractorImpl: OfflineInteractor {
override fun parseTextToList(firebaseVisionTextString: String): MutableList<String> {
val ingredientsList: MutableList<String> = firebaseVisionTextString.split(",").map { it.trim() }.toMutableList()
return ingredientsList
}
override fun readCsvFromAssetFolder(inputStream: InputStream): List<String> {
val csvLine: ArrayList<String> = ArrayList()
var content: Array<String>?
try
{
val br = BufferedReader(InputStreamReader(inputStream))
for (line in br.lines())
{
content = line.split((",").toRegex()).dropLastWhile{ it.isEmpty() }.toTypedArray()
csvLine.add(content[0].substringBefore(";"))
}
br.close()
}
catch (e: IOException) {
e.printStackTrace()
}
return csvLine
}
}
Test Results
java.lang.AssertionError:
Expected :[dried bonito extract, ketchup, millet, corn & wheat protein]
Actual :[]
Like second said, since you mocked offlineViewModel it is going to return an empty string, unless you define something for it to return using when().
Source: https://github.com/mockito/mockito/wiki/FAQ#what-values-do-mocks-return-by-default

Regex to match all '(def.+?})'

Pattern (def.+?}) matches the first Scala method :
object defvaltest {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
val str = "object t extends App { def one = { } def two = { } //Examples one two }"
//> str : String = object t extends App { def one = { } def two = { } //Example
//| s one two }
val Pattern = "(def.+?})".r //> Pattern : scala.util.matching.Regex = (def.+?})
Pattern.findFirstIn(str).get //> res0: String = def one = { }
}
How to match all Scala methods as List[String]
So instead of
res0: String = def one = { }
return
res0: List[String] = List("def one = { }" , "def two = { }")
You are looking for just one match with findFirstIn. To look for multiple matches, you need findAllIn:
val str = "object t extends App { def one = { } def two = { } //Examples one two }"
val Pattern = "(def.+?})".r
val res = Pattern.findAllIn(str)
res.foreach {m =>
println(m)
}
Output of the demo:
def one = { }
def two = { }

Get object of case class from regex match

i'm working on scraping data from a webpage with scala regex-es, but i encountered problem with parsing result to object of some case class-es.
In following snippet i managed to scrape all the data, but i have no clue how to parse 3 elements from an iterator. I thought about something like:
val a :: b :: c :: _ = result.group(0).iDontKnowWha
Any ideas what can i do?
import model.FuneralSchedule
import play.api.libs.json.Json
import scala.io.Source
var date = "2015-05-05"
val source = Source.fromURL("http://zck.krakow.pl/?pageId=16&date=" + date).mkString
val regex = "(?s)<table>.+?(Cmentarz.+?)<.+?</table>".r
var thing: List[FuneralSchedule] = List()
var jsonFeed: List[Funeral] = List()
val regMatcher = "("
case class Funeral(hour: String, who: String, age: String) {
override def toString: String = {
"Cos"
}
}
//implicit val format = Json.format[Funeral]
val out = regex.findAllIn(source).matchData foreach { table =>
thing ::= FuneralSchedule(table.group(1), clearStrings(table.group(0)))
"""<tr\s?>.+?</\s?tr>""".r.findAllIn(clearStrings(table.group(0))).matchData foreach { tr =>
//TODO: Naprawic bo szlak trafia wydajnosc
val temp = """<td\s?>.+?</\s?td>""".r.findAllIn(tr.group(0)).matchData.foreach {
elem => println(elem)
}
//println(Json.toJson(thingy))
}
println("Koniec tabeli")
}
thing
//Json.toJson(jsonFeed)
println(removeMarkers("<td > <td> Marian Debil </ td>"))
def removeMarkers(s: String) = {
s.replaceAll( """(</?\s?td\s?>)""", "")
}
def clearStrings(s: String) = {
val regex = "((class=\".+?\")|(id=\".+?\")|(style=\".+?\")|(\\n))"
s.replaceAll(regex, "")
}
One way of doing it would be converting it to a Stream and matching it using stream's operators like this:
val a #:: b #:: c #:: _ = """([a-z]){1}""".r.findAllIn("a b c").toStream
then a, b and c is what you're looking for

Scala - replaceAllIn

First off, I'm new to Scala.
I'm trying to make a template parser in Scala (similar to Smarty (PHP)). It needs to search through the document, replacing anything inside "{{ }}" tags, with anything provided in the HashMap.
I'm currently stuck here:
import scala.collection.mutable.HashMap
import scala.io.Source
class Template(filename: String, vars: HashMap[Symbol, Any]) {
def parse() = {
var contents = Source.fromFile(filename, "ASCII").mkString
var rule = """\{\{(.*)\}\}""".r
//for(rule(v) <- rule findAllIn contents) {
// yield v
//}
//rule.replaceAllIn(contents, )
}
}
var t = new Template("FILENAME", new HashMap[Symbol, Any])
println(t.parse)
The part's that I've commented are things that I've thought about doing.
Thanks
I've come a little further...
import scala.collection.mutable.HashMap
import scala.io.Source
import java.util.regex.Pattern
import java.util.regex.Matcher
class Template(filename: String, vars: HashMap[Symbol, Any]) {
def findAndReplace(m: Matcher)(callback: String => String):String = {
val sb = new StringBuffer
while (m.find) {
m.appendReplacement(sb, callback(m.group(1)))
}
m.appendTail(sb)
sb.toString
}
def parse() = {
var contents = Source.fromFile(filename, "ASCII").mkString
val m = Pattern.compile("""\{\{(.*)\}\}""").matcher(contents)
findAndReplace(m){ x => x }
}
}
var t = new Template("FILENAME.html", new HashMap[Symbol, Any])
println(t.parse)
At the moment it just currently adds whatever was inside of the tag, back into the document. I'm wondering if there is an easier way of doing a find-and-replace style regexp in Scala?
I'd do it like this (String as key instead of Symbol):
var s : String = input // line, whatever
val regexp = """pattern""".r
while(regexp findFirstIn s != None) {
s = regexp replaceFirstIn (s, vars(regexp.findFirstIn(s).get))
}
If you prefer not using var, go recursive instead of using while. And, of course, a stringbuilder would be more efficient. In that case, I might do the following:
val regexp = """^(.*?)(?:{{(pattern)}})?""".r
for(subs <- regexp findAllIn s)
subs match {
case regexp(prefix, var) => sb.append(prefix); if (var != null) sb.append("{{"+vars(var)+"}}")
case _ => error("Shouldn't happen")
}
That way you keep appending the non-changing part, followed by the next part to be replaced.
There is a flavor of replaceAllIn in util.matching.Regex that accepts a replacer callback. A short example:
import util.matching.Regex
def replaceVars(r: Regex)(getVar: String => String) = {
def replacement(m: Regex.Match) = {
import java.util.regex.Matcher
require(m.groupCount == 1)
Matcher.quoteReplacement( getVar(m group 1) )
}
(s: String) => r.replaceAllIn(s, replacement _)
}
This is how we would use it:
val r = """\{\{([^{}]+)\}\}""".r
val m = Map("FILENAME" -> "aaa.txt",
"ENCODING" -> "UTF-8")
val template = replaceVars(r)( m.withDefaultValue("UNKNOWN") )
println( template("""whatever input contains {{FILENAME}} and
unknown key {{NOVAL}} and {{FILENAME}} again,
and {{ENCODING}}""") )
Note Matcher.quoteReplacement escapes $ characters in the replacement string. Otherwise you may get java.lang.IllegalArgumentException: Illegal group reference, replaceAll and dollar signs. See the blog post on why this may happen.
Here is also interesting way how to do the same using functions compose:
val Regexp = """\{\{([^{}]+)\}\}""".r
val map = Map("VARIABLE1" -> "VALUE1", "VARIABLE2" -> "VALUE2", "VARIABLE3" -> "VALUE3")
val incomingData = "I'm {{VARIABLE1}}. I'm {{VARIABLE2}}. And I'm {{VARIABLE3}}. And also {{VARIABLE1}}"
def replace(incoming: String) = {
def replace(what: String, `with`: String)(where: String) = where.replace(what, `with`)
val composedReplace = Regexp.findAllMatchIn(incoming).map { m => replace(m.matched, map(m.group(1)))(_) }.reduceLeftOption((lf, rf) => lf compose rf).getOrElse(identity[String](_))
composedReplace(incomingData)
}
println(replace(incomingData))
//OUTPUT: I'm VALUE1. I'm VALUE2. And I'm VALUE3. And also VALUE1