1

I have a string like this:

str = "something move 11 something move 12 something 13 copy 14 15"

where the "something" means some text, or no text at all.
and as a result I want to have a list like:

[('move', 11, ''), ('move', 12, 13), ('copy', 14, 15)]

I tried using this:

re.findall('(move|copy).+?([0-9]+).+?([0-9]+)*', str)

but it gives my the output:

[('move', 11, ''), ('move', 12, ''), ('copy', 14, '')]

I understand that is because the last number is optional, but I just have no idea how I could it get working.

How can I do this?

1
  • You cannot do it if you expect any number of arguments to the commands. You can only tokenize the string and pick out the commands from an array of tokens. Commented Jan 23, 2013 at 20:48

2 Answers 2

1

Based on @Ashwini Chaudhary's answer:

#!/usr/bin/env python
import re

commands = "copy move".split()
input_string  = "something move 11 something move 12 something 13 copy 14 15"
tokens = iter(re.split("(%s)" % "|".join(map(re.escape, commands)), input_string))
result = []
for tok in tokens:
     if tok in commands:
        args = re.findall(r"\d+", next(tokens, ""))
        result.append((tok,) + tuple(args) + ("",)*(2 - len(args)))
print(result)

Output

[('move', '11', ''), ('move', '12', '13'), ('copy', '14', '15')]

To limit each command to two arguments, just use slicing: tuple(arg[:2]).

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

Comments

1

You could use a regular expression (with lookbehind and lookahead):

In [1]: import re

In [2]: tokens = "something move 11 something move 12 something 13 copy 14 15"

In [3]: split_movements = re.split('(?<=\d)\s(?!\d+)', tokens)

In [4]: split_movements
Out[4]: ['something move 11', 'something move 12', 'something 13', 'copy 14 15']

In [5]: movements = [re.split('\s(?=\d+)', m) for m in split_movements]

In [6]: movements
Out[6]: 
[['something move', '11'],
 ['something move', '12'],
 ['something', '13'],
 ['copy', '14', '15']]

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.