split strings without removing splitter

Viewed 55

I have the following text,

text = "12345678 abcdefg 37394822 gdzdnhqihdzuiew 09089799 78998728 gdjewdwq"

And I want the output be:

12345678 abcdefg
37394822 gdzdnhqihdzuiew 
09089799 
78998728 gdjewdwq

I tried "re.split("\d{8}", text)", but the result is incorrect. How to get the correct output?

4 Answers

IIUC, you looking to pair the numeric part with the alphanumeric and numeric will always be the first on each line

not an elegant of solution but addresses the question

splitted_txt = txt.split(' ')
i=0
while (i < (len(splitted_txt))):
    if (splitted_txt[i].isdigit() & ~(splitted_txt[i+1].isdigit())  ):
        print(splitted_txt[i], splitted_txt[i+1] )
        i+=1
    else:
        print(splitted_txt[i])
    i+=1
12345678 abcdefg
37394822 gdzdnhqihdzuiew
09089799
78998728 gdjewdwq

I prefer @Itagaki's answer but it's worth noting that findall could also be used:

import re
text = "12345678 abcdefg 37394822 gdzdnhqihdzuiew 09089799 78998728 gdjewdwq"
re.findall(r"\d+(?:\s+[a-z]+)?", text)
  #=> ['12345678 abcdefg', '37394822 gdzdnhqihdzuiew', '09089799', '78998728 gdjewdwq']

Demo

The regular expression can be broken down as follows.

\d+       # match one or more digits
(?:       # begin a non-capture group
  \s+     # match one or more whitespaces
  [a-z]+  # match one or more lowercase letters
)         # end non-capture group
?         # make non-capture group optional

If it were required that there be exactly 8 digits and that the strings lowercase letters have lengths between (say) 7 and 15 (as in the example), the regex would be modified slightly:

r"\d{8}(?:\s+[a-z]{7,15})?"

If you want to match 8 digits, you can use:

\b\d{8}\b.*?(?=\s*(?:\b\d{8}\b|$))

Explanation

  • \b\d{8}\b Match 8 digits surrounded by word boundaries to prevent partial matches
  • .*? Match any char, as least as possible
  • (?= Positive lookahead
    • \s* Match optional whitespace chars
    • (?:\b\d{8}\b|$) Match either 8 digits or assert the end of the string
  • ) Close lookahead

Regex demo | Python demo

Example

import re

pattern = r"\b\d{8}\b.*?(?=\s*(?:\b\d{8}\b|$))"
s = "12345678 abcdefg 37394822 gdzdnhqihdzuiew 09089799 78998728 gdjewdwq"

print(re.findall(pattern, s))

Output

['12345678 abcdefg', '37394822 gdzdnhqihdzuiew', '09089799', '78998728 gdjewdwq']
Related