Ganga
Ganga

Reputation: 923

Groovy - Convert String to Nested Lists

In groovy, I am trying to convert the following string into separate pairs, which is the form of collections. I tried using eval in groovy, but it is currently throwing an exception. Is there any elegant way to convert this string.

[[u'abcd', u'12345'], [u'cmnln', u'12121'], [u'mnmnnkj', u'11212']]
String str = "[[u'abcd', u'12345'], [u'cmnln', u'12121'], [u'mnmnnkj', u'11212']]"
list2 = Eval.me(str)

Expected Result:

Pairs: abcd, 12345 cmnln, 12121 mnmnnkj, 12121

Actual Result:

hudson.remoting.ProxyException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 1: unexpected token: abcd @ line 1, column 4.
   [[u'abcd', u'12345'], [u'cmnln', u'12121'], [u'mnmnnkj', u'11212']]
      ^

1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
    at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:150)
    at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:120)
    at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:132)
    at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:350)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:144)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:110)
    at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:234)
    at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:168)
    at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:943)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:605)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
    at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
    at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:584)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:623)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:594)
    at groovy.util.Eval.me(Eval.java:69)
    at groovy.util.Eval.me(Eval.java:52)
    at groovy.util.Eval$me.callStatic(Unknown Source)

Upvotes: 0

Views: 235

Answers (2)

cfrick
cfrick

Reputation: 37008

If you love overkill, like to wait half a second for the result, and think it's a good time to start using Python 2 now, this works too:

@Grab('org.python:jython-standalone:2.7.1')
import org.python.util.PythonInterpreter

String str = "[[u'abcd', u'12345'], [u'cmnln', u'12121'], [u'mnmnnkj', u'11212']]"

println(new PythonInterpreter().withCloseable{ it.eval str })
// ⇒ [[abcd, 12345], [cmnln, 12121], [mnmnnkj, 11212]]

Upvotes: 0

Jeff Scott Brown
Jeff Scott Brown

Reputation: 27220

Your attempt:

String str = "[[u'abcd', u'12345'], [u'cmnln', u'12121'], [u'mnmnnkj', u'11212']]"
list2 = Eval.me(str)

That is not going to work because the value you are passing to Eval.me(...) is not valid Groovy code. In particular, expressions like u'abcd' and u'12345' are not valid.

You will need to write a parser or at least some parsing code to break that up and how to do that depends on knowledge of the data. For example, if you know every one of those String values are prefixed with u and u never appears in the data, you could do something naive like this:

        String input = "[[u'abcd', u'12345'], [u'cmnln', u'12121'], [u'mnmnnkj', u'11212']]"
        String processedInput = input.replaceAll 'u', ''
        def result  = Eval.me processedInput
        println result

If a u might occur in the data then you will need a more sophisticated regular expression.

Upvotes: 3

Related Questions