diff --git a/text-processing/README.md b/text-processing/README.md new file mode 100644 index 0000000..94fb73f --- /dev/null +++ b/text-processing/README.md @@ -0,0 +1,37 @@ +text-processing +===== + +### Общее описание + +Модуль содержит функционал: +- Генерация "Replace" шаблона из регулярного выражения и возможность подстановки его в строку, +- Генерация Placeholder из регулярного выражения, +- Генерация маски для `EditText` из регулярного выражения и возможность его подстановки. + +Модуль содержит класс `TextFormatter`, который в качестве аргумента принимает `String` в виде регулярного выражения. +* Функция `getFormattedText` - принимает входящий параметр в виде строки для форматирования, возвращает отформатированную строку, +* Функция `getPlaceholder` - возвращает Placeholder соответствующий регулярному выражению, +* Функция `getRegexReplace` - возвращает "Replace" шаблон регулярного выражения, +* Функция `mask` - принимает входящим параметром `EditText` и применяет к нему маску сгенерированую по регулярному выражению. + +### Пример применения `textFormatter` + +```kotlin +class MainActivity : Activity() { + + /** + * replace шаблон - $1/$2 + * placeholder - 12/34 + * **/ + private val textFormatter = TextFormatter("(\\d{2})\\/?(\\d{2})") + private lateinit var editText: EditText + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + editText = findViewById(R.id.editText) + editText.hint = textFormatter.getPlaceholder() //В результате placeholder будет 12/34 + textFormatter.mask(editText) //Применение маски соответствующей регулярному выражению из textFormatter + } +} +``` \ No newline at end of file diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/TextFormatter.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/TextFormatter.kt index 99eb9ea..4dde18d 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/TextFormatter.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/TextFormatter.kt @@ -1,6 +1,6 @@ package ru.touchin.roboswag.textprocessing -import android.widget.TextView +import android.widget.EditText import ru.touchin.roboswag.textprocessing.generators.DecoroMaskGenerator import ru.touchin.roboswag.textprocessing.generators.PlaceholderGenerator import ru.touchin.roboswag.textprocessing.generators.regexgenerator.RegexReplaceGenerator @@ -8,23 +8,28 @@ import ru.touchin.roboswag.textprocessing.generators.regexgenerator.RegexReplace class TextFormatter(private val regex: String) { private val regexReplaceGenerator = RegexReplaceGenerator() + private val decoroMaskGenerator = DecoroMaskGenerator() + private val pcreGeneratorItem = regexReplaceGenerator.regexToRegexReplace(regex) + private val regexReplaceString = pcreGeneratorItem.regexReplaceString + private val matrixOfSymbols = pcreGeneratorItem.matrixOfSymbols + private val placeholderGenerator = PlaceholderGenerator(matrixOfSymbols) - fun getFormatText(inputText: String) = inputText.replace(Regex(regex), regexReplaceString) + fun getFormattedText(inputText: String) = inputText.replace(Regex(regex), regexReplaceString) - fun getPlaceholder() = placeholderGenerator.getPlaceholder() + fun getPlaceholder() = placeholderGenerator.placeholder fun getRegexReplace() = regexReplaceString - fun mask(textView: TextView) { + fun mask(editText: EditText) { val formatWatcher = decoroMaskGenerator.mask( - placeholderGenerator.getPlaceholder(), + placeholderGenerator.placeholder, matrixOfSymbols ) - formatWatcher.installOn(textView) + formatWatcher.installOn(editText) } -} \ No newline at end of file +} diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/DecoroMaskGenerator.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/DecoroMaskGenerator.kt index c5178a4..d8d1986 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/DecoroMaskGenerator.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/DecoroMaskGenerator.kt @@ -12,16 +12,13 @@ class DecoroMaskGenerator { * если возможный символ всего один, то символ хардкодится в слот * **/ fun mask(placeholder: String, matrixOfSymbols: Matrix): MaskFormatWatcher { - val slots = mutableListOf() - for (i in placeholder.indices) { - slots.add( - if (matrixOfSymbols[i].size == 1) { - PredefinedSlots.hardcodedSlot(placeholder[i]) - } else { - CustomValidator.customSlot(matrixOfSymbols[i]) - } - ) + val slots = placeholder.mapIndexed { index, char -> + if (matrixOfSymbols[index].size == 1) { + PredefinedSlots.hardcodedSlot(char) + } else { + CustomValidator.customSlot(matrixOfSymbols[index]) + } } return MaskFormatWatcher(MaskImpl.createTerminated(slots.toTypedArray())) } -} \ No newline at end of file +} diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/Matrix.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/Matrix.kt index 1d20b16..90552f6 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/Matrix.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/Matrix.kt @@ -1,3 +1,3 @@ package ru.touchin.roboswag.textprocessing.generators -typealias Matrix = List> \ No newline at end of file +typealias Matrix = List> diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/PlaceholderGenerator.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/PlaceholderGenerator.kt index 3e9033a..ed3c31c 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/PlaceholderGenerator.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/PlaceholderGenerator.kt @@ -2,9 +2,10 @@ package ru.touchin.roboswag.textprocessing.generators class PlaceholderGenerator(matrixOfSymbols: Matrix) { - private var placeholder: String = "" + val placeholder = generatePlaceholder(matrixOfSymbols) - init { + private fun generatePlaceholder(matrixOfSymbols: Matrix): String { + val placeholderStringBuilder = StringBuilder() val indexes = hashMapOf, Int>() for (listOfSymbols in matrixOfSymbols) { indexes[listOfSymbols] = 0 @@ -13,18 +14,17 @@ class PlaceholderGenerator(matrixOfSymbols: Matrix) { if (listOfSymbols.isEmpty()) continue /** Если элемент без повторений **/ if (listOfSymbols.size == 1) { - placeholder += listOfSymbols[0] + placeholderStringBuilder.append(listOfSymbols[0]) continue } indexes[listOfSymbols]?.let { var index = it if (listOfSymbols.size <= index) index = 0 - placeholder += listOfSymbols[index] + placeholderStringBuilder.append(listOfSymbols[index]) index++ indexes[listOfSymbols] = index } } + return placeholderStringBuilder.toString() } - - fun getPlaceholder() = placeholder -} \ No newline at end of file +} diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorItem.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorItem.kt index 5b57d8b..abf8921 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorItem.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorItem.kt @@ -5,4 +5,4 @@ import ru.touchin.roboswag.textprocessing.generators.Matrix class PCREGeneratorItem( val regexReplaceString: String, val matrixOfSymbols: Matrix -) \ No newline at end of file +) diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorListener.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorListener.kt index b42fb1d..9bb8305 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorListener.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/PCREGeneratorListener.kt @@ -4,12 +4,15 @@ import ru.touchin.roboswag.textprocessing.pcre.parser.PCREBaseListener import ru.touchin.roboswag.textprocessing.pcre.parser.PCREParser class PCREGeneratorListener : PCREBaseListener() { + /** * Лист для placeholder, где индекс - номер буквы для placeholder * значение - возможные символы для placeholder * **/ private val matrixOfSymbols = mutableListOf>() + private var currentGroupIndex = 1 + private var regexReplaceString = "" /** Элемент поиска с регулярного выражения @@ -72,8 +75,8 @@ class PCREGeneratorListener : PCREBaseListener() { fun toPCREGeneratorItem() = PCREGeneratorItem( regexReplaceString, - matrixOfSymbols.map { it -> - it.filter { + matrixOfSymbols.map { chars -> + chars.filter { it != '\\' } } @@ -100,4 +103,4 @@ class PCREGeneratorListener : PCREBaseListener() { val endRange = atomStr[atomStr.length - 2] return startRange.rangeTo(endRange).toMutableList() } -} \ No newline at end of file +} diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/RegexReplaceGenerator.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/RegexReplaceGenerator.kt index 146b181..df36ac6 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/RegexReplaceGenerator.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/generators/regexgenerator/RegexReplaceGenerator.kt @@ -10,12 +10,18 @@ class RegexReplaceGenerator { fun regexToRegexReplace(regex: String): PCREGeneratorItem { val stringStream = CharStreams.fromString(regex) + val lexer = PCRELexer(stringStream) + val parser = PCREParser(CommonTokenStream(lexer)) + val parseContext = parser.parse() + val walker = ParseTreeWalker() + val pcreGeneratorListener = PCREGeneratorListener() + walker.walk(pcreGeneratorListener, parseContext) return pcreGeneratorListener.toPCREGeneratorItem() } -} \ No newline at end of file +} diff --git a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/validators/CustomValidator.kt b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/validators/CustomValidator.kt index ccab533..da6ef2e 100644 --- a/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/validators/CustomValidator.kt +++ b/text-processing/src/main/java/ru/touchin/roboswag/textprocessing/validators/CustomValidator.kt @@ -13,4 +13,4 @@ class CustomValidator private constructor( override fun validate(value: Char): Boolean { return slotSymbols.contains(value) } -} \ No newline at end of file +} diff --git a/text-processing/src/main/res/values/common_resources.xml b/text-processing/src/main/res/values/common_resources.xml deleted file mode 100644 index 045e125..0000000 --- a/text-processing/src/main/res/values/common_resources.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/text-processing/src/test/java/ru/touchin/roboswag/textprocessing/TextFormatterTest.kt b/text-processing/src/test/java/ru/touchin/roboswag/textprocessing/TextFormatterTest.kt index 3db4c5a..491bfb6 100644 --- a/text-processing/src/test/java/ru/touchin/roboswag/textprocessing/TextFormatterTest.kt +++ b/text-processing/src/test/java/ru/touchin/roboswag/textprocessing/TextFormatterTest.kt @@ -11,7 +11,7 @@ class TextFormatterTest { val inputText = "0622" val item = TextFormatter(regex) Assert.assertEquals("$1\\/$2", item.getRegexReplace()) - Assert.assertEquals("06/22", item.getFormatText(inputText)) + Assert.assertEquals("06/22", item.getFormattedText(inputText)) Assert.assertEquals("12/34", item.getPlaceholder()) } @@ -21,7 +21,7 @@ class TextFormatterTest { val inputText = "1234345612353534" val item = TextFormatter(regex) Assert.assertEquals("\$1 \$2 \$3 \$4", item.getRegexReplace()) - Assert.assertEquals("1234 3456 1235 3534", item.getFormatText(inputText)) + Assert.assertEquals("1234 3456 1235 3534", item.getFormattedText(inputText)) Assert.assertEquals("1234 5678 9012 3456", item.getPlaceholder()) } @@ -31,7 +31,7 @@ class TextFormatterTest { val inputText = "9091344422" val item = TextFormatter(regex) Assert.assertEquals("\\+7 \\($1\\) $2 $3 $4", item.getRegexReplace()) - Assert.assertEquals("+7 (909) 134 44 22", item.getFormatText(inputText)) + Assert.assertEquals("+7 (909) 134 44 22", item.getFormattedText(inputText)) Assert.assertEquals("+7 (123) 456 78 90", item.getPlaceholder()) } @@ -41,7 +41,7 @@ class TextFormatterTest { val inputText = "IVБЮ349823" val item = TextFormatter(regex) Assert.assertEquals("\$1-\$2 № \$3", item.getRegexReplace()) - Assert.assertEquals("IV-БЮ № 349823", item.getFormatText(inputText)) + Assert.assertEquals("IV-БЮ № 349823", item.getFormattedText(inputText)) Assert.assertEquals("AB-АБ № 123456", item.getPlaceholder()) } @@ -51,7 +51,7 @@ class TextFormatterTest { val inputText = "5332.4" val item = TextFormatter(regex) Assert.assertEquals("\$1\$2 ₽", item.getRegexReplace()) - Assert.assertEquals("5332.4 ₽", item.getFormatText(inputText)) + Assert.assertEquals("5332.4 ₽", item.getFormattedText(inputText)) Assert.assertEquals("1.2 ₽", item.getPlaceholder()) } -} \ No newline at end of file +}