Groovy скрипт для потоковых наборов для разбора строки около 1500 символов - PullRequest
2 голосов
/ 01 мая 2019

Это для потоковых наборов, я пытаюсь написать отличный сценарий. У меня есть строка длиной 1500 символов. Без разделителя. В шаблоне первые 4 символа - некоторый код, следующие 4 символа - длина слова, за которым следует слово. Снова это как 4 символа некоторого кода и 4 символа длины слова, сопровождаемого словом. например 22010005PHONE00010002IN00780004ROSE

Когда вы декодируете, это будет похоже на

2201 - код 0005 - длина слова ТЕЛЕФОН - Слово

0001 - код 0002 - длина слова IN - Word

0078 - код 0004 - длина слова РОЗА - Слово и так далее ..

Мне нужна помощь в скрипте groovy для создания строки, если код начинается с 00. Таким образом, последняя строка будет INROSE.

Я пытаюсь использовать цикл while и str: substring. Любая помощь очень ценится.

Спасибо

def dtx_buf = record.value['TXN_BUFFER']
def fieldid = []
def fieldlen = []
def dtx_out = []
def i = 13
def j = 0
while (i < dtx_buf.size())
{    
//   values = record.value['TXN_BUFFER']
    fieldid[j] = str.substring(values,j,4)      
    output.write(record)
} 

Ожидаемый результат "INROSE"

1 Ответ

4 голосов
/ 01 мая 2019

Один из способов - написать итератор, содержащий правила для анализа ввода:

class Tokeniser implements Iterator {
    String buf
    String code
    String len
    String word

    // hasNext is true if there's still chars left in `buf`        
    boolean hasNext() { buf }

    Object next() {
        // Get the code and the remaining string
        (code, buf) = token(buf)

        // Get the length and the remaining string
        (len, buf) = token(buf)

        // Get the word (of the given length), and the remaining string
        (word, buf) =  token(buf, len as Integer)

        // Return a map of the code and the word
        [code: code, word: word]
    }

    // This splits the string into the first `length` chars, and the rest
    private token(String input, int length = 4) {
        [input.take(length), input.drop(length)]
    }

}

Затем мы можем использовать это для:

def result = new Tokeniser(buf: '22010005PHONE00010002IN00780004ROSE')
    .findAll { it.code.startsWith('00') }
    .word
    .join()

И результат INROSE

Бери 2

Мы можем попробовать другой итерационный метод без внутреннего класса, чтобы проверить, работает ли он лучше в вашей среде:

def input = '22010005PHONE00010002IN00780004ROSE'
def pos = 0
def words = []

while (pos < input.length() - 8) {
    def code = input.substring(pos, pos + 4)
    def len = input.substring(pos + 4, pos + 8) as Integer
    def word = input.substring(pos + 8, pos + 8 + len)
    if (code.startsWith('00')) {
        words << word
    }
    pos += 8 + len
}

def result = words.join()
...