13

I need to split a string using python but only on the first instance of the delimiter in the string.

My code:

for line in conf.readlines():
    if re.search('jvm.args',line):
        key,value= split('=',line)
        default_args=val

The problem is line, which contains jvm.args looks like this:

'jvm.args = -Dappdynamics.com=true, -Dsomeotherparam=false,'

I want my code to split jvm.args into key and value variables incidently upon the first '='. Does re.split do this by default? If not a suggestion would be appreciated!

3
  • 2
    Since you're only interested in the the first delimiter, why not just find the match for the delimiter, with a scan of the string? Then you can just extract the two slices with line[:pos] and line[pos+1:]. Commented Jun 13, 2012 at 6:18
  • @user1371011 expected output? Commented Jun 13, 2012 at 6:26
  • 1
    You don't need readlines(), stores a list in memory which is unnecessary. Just iterate over each line by simply doing this: for line in conf Commented Jun 13, 2012 at 10:40

6 Answers 6

25

This is what str.partition is for:

>>> 'jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false,'.partition('=')
('jvm.args', '=', ' -Dappdynamics.com=true, -Dsomeotherparam=false,')

From the docs:

str.partition(sep)

Split the string at the first occurrence of sep, and return a 3-tuple containing the part before the separator, the separator itself, and the part after the separator. If the separator is not found, return a 3-tuple containing the string itself, followed by two empty strings.

New in version 2.5.

Sign up to request clarification or add additional context in comments.

1 Comment

@BurhanKhalid Yes, partition is optimized for this.
13

From the split documentation

str.split([sep[, maxsplit]])

Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements)

>>> 'jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false,'.split('=',1)
['jvm.args', ' -Dappdynamics.com=true, -Dsomeotherparam=false,']

Comments

2

I think this should work :

lineSplit = line.split("=")
key = lineSplit[0]
value = "=".join(lineSplit[1:])

As someone suggested in comments: you can just parse through string once and locate "=" , followed by splitting it from that point.

4 Comments

-1 value = ','.join((key,"=".join(lineSplit[1:]))) is the correct way to do it.
names_with_underscores are encouraged in python.
@jamylak i switch between java and python too frequently and this is the pattern I follow :) Thanks for suggestion though !
@AshwiniChaudhary The question says "I need to split a string using python but only on the first instance of the delimter in the string." and my code does the same. What you wrote, gives more explicit separation of arguments though.
1

I guess I'll turn my comment into (untested) code because it might be useful at a lower level than str.partition(). For example, for a more complicated delimiter requiring a regular expression, you could use re.match() to find pos. But Triptych's suggestion got my vote.

Here you go:

pos = -1
for i, ch in enumerate(line):
    if ch == '=':
        pos = i
        break
if pos < 0: raise myException()

key = line[:pos]
value = line[pos+1:]

Comments

0

I'd skip using regular expressions completely, for a simple string comparison they are not really required.

The example code uses an inline method to yield key,value tuples that the dict builtin uses to generate a dictionary (I've not bothered with the file iteration code, your example is correct there):

line="jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false, "

# Detect a line that starts with jvm.args
if line.strip().startswith('jvm.args'):
    # Only interested in the args
    _, _, args = line.partition('=')

    # Method that will yield a key, value tuple if item can be converted
    def key_value_iter(args):
        for arg in args:
            try:
                key, value = arg.split('=')
                # Yield tuple removing the -d prefix from the key
                yield key.strip()[2:], value
            except:
                # A bad or empty value, just ignore these
                pass

    # Create a dict based on the yielded key, values
    args = dict(key_value_iter(args.split(',')))

print args will return:

{'appdynamics.com': 'true', 'someotherparam': 'false'}

I assume this is what you are actually after ;)

Comments

0

As suggested in your previous question, ConfigParser is the most straightforward way:

import ConfigParser

from io import StringIO

conf = u"""
[options]
foo=bar
jvm.args= -Dappdynamics.com=true, -Dsomeotherparam=false, 
"""

config = ConfigParser.ConfigParser()
config.readfp(StringIO(conf))
print config.get('options', 'jvm.args')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.