0

I have a list of strings similar to the one below:

l = ['ad2g3f234','4jafg32','fg23g523']

For each string in l, I want to delete every digit (except for 2 and 3 if they appear as 23). So in this case, I want the following outcome:

n = ['adgf23','jafg','fg23g23']

How do I go about this? I tried re.findall like:

w = [re.findall(r'[a-zA-Z]+',t) for t in l]

but it doesn't give my desired outcome.

4 Answers4

0

One way would be just to replace the string twice:

[re.sub("\d", "", i.replace("23", "*")).replace("*", "23") for i in l]

Output:

['adgf23', 'jafg', 'fg23g23']
Chris
  • 29,127
  • 3
  • 28
  • 51
0

Use a placeholder with re.sub

l = ['ad2g3f234','4jafg32','fg23g523']
w = [re.sub('#','23',re.sub('\d','',re.sub('23','#',t))) for t in l]

['adgf23', 'jafg', 'fg23g23'] 

EDIT

As answered by Chris, the approach is the same although string replace will be a better alternative stack_comparison

Agnij
  • 561
  • 3
  • 13
0

Using re.sub with function

import re

def replace(m):
    if m.group() == '23':
        return m.group()
    else:
        return ''
    
l = ['ad2g3f234','4jafg32','fg23g523']
w = [re.sub(r'23|\d', replace, x) for x in l]

#w: ['adgf23', 'jafg', 'fg23g23']

Explanation

re.sub(r'23|\d', replace, x)
- checks first for 23, next for a digit
- replace function leaves alone match with 23
- changes match with digit to null string.
DarrylG
  • 16,732
  • 2
  • 17
  • 23
0

You can capture 23 in a group, and remove all other digits. In the replacement, use the group which holds 23 if it is there, else replace with an empty string.

import re

l = ['ad2g3f234', '4jafg32', 'fg23g523']

result = [
    re.sub(
        r"(23)|(?:(?!23)\d)+", 
        lambda m: m.group(1) if m.group(1) else "", s) for s in l
]
print(result)

Output

['adgf23', 'jafg', 'fg23g23']

Python demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • could you explain what the lambda function is doing? thanks –  Oct 25 '21 at 20:02
  • @NewbieAF The lambda is the callback function for re.sub See https://docs.python.org/3/library/re.html#re.sub where is this code example `m` is the 'matchobj' – The fourth bird Oct 25 '21 at 20:26
  • 1
    The function checks if the match object has a capture group 1 which contains the value 23. If there is a capture group 1 present, then put back the 23. If there is no group 1 present, then the match contains all other digits except 23. That match is then replaced by an empty string. – The fourth bird Oct 25 '21 at 20:34
  • How do I exclude more characters? For example, if I want to exclude “-“, “+”, “{}” and “()” as well as any digit not making “23”? –  Oct 25 '21 at 22:17
  • @NewbieAF The pattern does not match `-` or `+` so they will stay in the string. – The fourth bird Oct 25 '21 at 23:10