Regex: Replace one pattern with another - python

I am trying to replace one regex pattern with another regex pattern.
st_srt = 'Awake.01x02.iNTERNAL.WEBRiP.XViD-GeT.srt'
st_mkv = 'Awake.S01E02.iNTERNAL.WEBRiP.XViD-GeT.mkv'
pattern = re.compile('\d+x\d+') # for st_srt
re.sub(pattern, 'S\1E\2',st_srt)
I know the use of S\1E\2 is wrong here. The reason am using \1 and \2 is to catch the value 01 and 02 and use it in S\1E\2.
My desired output is:
st_srt = 'Awake.S01E02.iNTERNAL.WEBRiP.XViD-GeT.srt'
So, what is the correct way to achieve this.

You need to capture what you're trying to preserve. Try this:
pattern = re.compile(r'(\d+)x(\d+)') # for st_srt
st_srt = re.sub(pattern, r'S\1E\2', st_srt)

Well, it looks like you already accepted an answer, but I think this is what you said you're trying to do, which is get the replace string from 'st_mkv', then use it in 'st_srt':
import re
st_srt = 'Awake.01x02.iNTERNAL.WEBRiP.XViD-GeT.srt'
st_mkv = 'Awake.S01E02.iNTERNAL.WEBRiP.XViD-GeT.mkv'
replace_pattern = re.compile(r'Awake\.([^.]+)\.')
m = replace_pattern.match(st_mkv)
replace_string = m.group(1)
new_srt = re.sub(r'^Awake\.[^.]+\.', 'Awake.{0}.'.format(replace_string), st_srt)
print new_srt

Try using this regex:
([\w+\.]+){5}\-\w+
copy the stirngs into here: http://www.gskinner.com/RegExr/
and paste the regex at the top.
It captures the names of each string, leaving out the extension.
You can then go ahead and append the extension you want, to the string you want.
EDIT:
Here's what I used to do what you're after:
import re
st_srt = 'Awake.01x02.iNTERNAL.WEBRiP.XViD-GeT.srt' // dont actually need this one
st_mkv = 'Awake.S01E02.iNTERNAL.WEBRiP.XViD-GeT.mkv'
replace_pattern = re.compile(r'([\w+\.]+){5}\-\w+')
m = replace_pattern.match(st_mkv)
new_string = m.group(0)
new_string += '.srt'
>>> new_string
'Awake.S01E02.iNTERNAL.WEBRiP.XViD-GeT.srt'

import re
st_srt = 'Awake.01x02.iNTERNAL.WEBRiP.XViD-GeT.srt'
st_mkv = 'Awake.S01E02.iNTERNAL.WEBRiP.XViD-GeT.mkv'
pattern = re.compile(r'(\d+)x(\d+)')
st_srt_new = re.sub(pattern, r'S\1E\2', st_srt)
print st_srt_new

Related

extract data from nested parenthesis?

I have a string:
test_string = 'RGBA(30(25VARGHK_65FVDFKDGV_10FVDSSLBA)_10UJN(85VOEZSR_5VAVUSR_10SQMCFE)_20BBLRG(SSLCN)_10UDSCT(80EDYFIH_10VAP_10SNE)_30EDU(50EDFva_50VAP)_10EDP(50EDFva_50SNE))'
I need to extract the data from the string and the final result should look like that:
RGBA,
30TCH:25VARGHK, 65FVDFKDGV, 10FVDSSLBA,
10UJN:85VOEZSR, 5VAVUSR, 5SQMCFE
....
and so on..
I thought using regex but it is not good solution here..
Regex will work fine. After you remove the outer I(), you have a many sets of "prefix" followed by a (group_of_data)
If you don't want trailing commas, try this
import re
regex = r"[^(]+\([^)]+\)"
s = 'RGBA(30(25VARGHK_65FVDFKDGV_10FVDSSLBA)_10UJN(85VOEZSR_5VAVUSR_10SQMCFE)_20BBLRG(SSLCN)_10UDSCT(80EDYFIH_10VAP_10SNE)_30EDU(50EDFva_50VAP)_10EDP(50EDFva_50SNE))'
first_start = s.index('(')
print(s[:first_start])
matches = re.finditer(regex, s[first_start+1:-1], re.MULTILINE)
for _, match in enumerate(matches, start=1):
g = match.group().lstrip('_')
data_start = g.index('(')
prefix = g[:data_start]
data = ', '.join(g[data_start + 1:-1].split('_'))
print(f'{prefix}:{data}')
Output
RGBA
30:25VARGHK, 65FVDFKDGV, 10FVDSSLBA,
10UJN:85VOEZSR, 5VAVUSR, 10SQMCFE
20BBLRG:SSLCN
10UDSCT:80EDYFIH, 10VAP, 10SNE
30EDU:50EDFva, 50VAP
10EDP:50EDFva, 50SNE
This seems to get you (almost) there -
[_.replace("(", ": ").replace("_", ", ") for _ in re.split(r"\)_", test_string)]
Output
['RGBA: 30TCH: 25VARGHK, 65FVDFKDGV, 10FVDSSLBA',
'10UJN: 85VOEZSR, 5VAVUSR, 10SQMCFE
'20BBLRG:SSLCN',
'10UDSCT:80EDYFIH, 10VAP, 10SNE
'30EDU:50EDF, 50VPC',
'10EDP:50EDF, 50SNELP))']
I think we may need a little more clarification on the logic. It looks like ( should translate into a :, but not every time. Here is my crack at it using regexes. This might not be exactly what you are looking for, but should be pretty close:
import re
def main():
test_string = 'RGBA(30(25VARGHK_65FVDFKDGV_10FVDSSLBA)_10UJN(85VOEZSR_5VAVUSR_10SQMCFE)_20BBLRG(SSLCN)_10UDSCT(80EDYFIH_10VAP_10SNE)_30EDURKA(50EDFL_50VAP)_10EDPJ(50EDFV_50SNOL))'
test_string = re.sub("\)_", ",\n", test_string)
test_string = re.sub("_", ",", test_string)
test_string = re.sub("\(", ":", test_string)
test_string = re.sub("\)\)", "", test_string)
print(test_string)
if __name__ == "__main__":
main()
results:
RGBA:30:25VARGHK,65FVDFKDGV,10FVDSSLBA,
10UJN:85VOEZSR,5VAVUSR,10SQMCFE,
20BBLRG:SSLCN,
10UDSCT:85EDYFIH,5VAPOR,10SQMCFE,
30EDURKA:70EDFL,30VAPOR,
10EDPJ:50EDFV,50SNOL
Pretty much just a series of regexes. Note that by using re.sub like this in an order, you clean the string as you go. You could certainly just fiddle the beginning of the string to change the first : to a ,\n but I'm not sure if the data you are getting in is always the same.

How to get only the alphanumeric characters that are before any special characters in a string?

Example:
string1 = '71B46>TC>77'
Is there a way to get the following without having a for loop:
output = '71B46'
I can't hardcode ">" because special characters vary.
Thank you.
text = "71B46>TC>77"
position = text.index('>')
result = text[0:position]
# 71B46
Update
import re
regex = r"[\W+]"
text = "71B46>TC>77"
position = re.search(regex, text).start()
print(text[0:position])
# 71B46
You should try this.
import re
start_pos = re.search(r'\W+', string1).start()
print(string1[0:start_pos])
Without using regular expressions. Filter for characters that are alphanumeric.
s = '71B46>TC>77'
modified = ''.join(filter(str.isalnum, s))
# or
modified = ''.join((c for c in s if c.isalnum()))
One-Liner-Solution
import re
get_chars_before_spl_chars = lambda string1 :re.findall("[\dA-Za-z]*",string1)[0]
get_chars_before_spl_chars('71B46>TC>77')
#'71B46'

regex to extract data between quotes

As title says string is '="24digit number"' and I want to extract number between "" (example: ="000021484123647598423458" should get me '000021484123647598423458').
There are answers that answer how to get data between " but in my case I also need to confirm that =" exist without capturing (there are also other "\d{24}" strings, but they are for other stuff) it.
I couldn't modify these answers to get what I need.
My latest regex was ((?<=\")\d{24}(?=\")) and string is ="000021484123647598423458".
UPDATE: I think I will settle with pattern r'^(?:\=\")(\d{24})(?:\")' because I just want to capture digit characters.
word = '="000021484123647598423458"'
pattern = r'^(?:\=\")(\d{24})(?:\")'
match = re.findall(pattern, word)[0]
Thank you all for suggestions.
You could have it like:
=(['"])(\d{24})\1
See a demo on regex101.com.
In Python:
import re
string = '="000021484123647598423458"'
rx = re.compile(r'''=(['"])(\d{24})\1''')
print(rx.search(string).group(2))
# 000021484123647598423458
Any one of the following works:
>>> st = '="000021484123647598423458"'
>>> import re
>>> re.findall(r'".*\d+.*"',st)
['"000021484123647598423458"']
or
>>> re.findall(r'".*\d{24}.*"',st)
['"000021484123647598423458"']
or
>>> re.findall(r'"\d{24}"',st)
['"000021484123647598423458"']

Python splitting string to find specific content

I am trying to split a string in python to extract a particular part. I am able to get the part of the string before the symbol < but how do i get the bit after? e.g. the emailaddress part?
>>> s = 'texttexttextblahblah <emailaddress>'
>>> s = s[:s.find('<')]
>>> print s
This above code gives the output texttexttextblahblah 
s = s[s.find('<')+1:-1]
or
s = s.split('<')[1][:-1]
cha0site's and ig0774's answers are pretty straightforward for this case, but it would probably help you to learn regular expressions for times when it's not so simple.
import re
fullString = 'texttexttextblahblah <emailaddress>'
m = re.match(r'(\S+) <(\S+)>', fullString)
part1 = m.group(1)
part2 = m.group(2)
Perhaps being a bit more explicit with a regex isn't a bad idea in this case:
import re
match = re.search("""
(?<=<) # Make sure the match starts after a <
[^<>]* # Match any number of characters except angle brackets""",
subject, re.VERBOSE)
if match:
result = match.group()

How can I get part of regex match as a variable in python?

In Perl it is possible to do something like this (I hope the syntax is right...):
$string =~ m/lalala(I want this part)lalala/;
$whatIWant = $1;
I want to do the same in Python and get the text inside the parenthesis in a string like $1.
If you want to get parts by name you can also do this:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcom Reynolds")
>>> m.groupdict()
{'first_name': 'Malcom', 'last_name': 'Reynolds'}
The example was taken from the re docs
See: Python regex match objects
>>> import re
>>> p = re.compile("lalala(I want this part)lalala")
>>> p.match("lalalaI want this partlalala").group(1)
'I want this part'
import re
astr = 'lalalabeeplalala'
match = re.search('lalala(.*)lalala', astr)
whatIWant = match.group(1) if match else None
print(whatIWant)
A small note: in Perl, when you write
$string =~ m/lalala(.*)lalala/;
the regexp can match anywhere in the string. The equivalent is accomplished with the re.search() function, not the re.match() function, which requires that the pattern match starting at the beginning of the string.
import re
data = "some input data"
m = re.search("some (input) data", data)
if m: # "if match was successful" / "if matched"
print m.group(1)
Check the docs for more.
there's no need for regex. think simple.
>>> "lalala(I want this part)lalala".split("lalala")
['', '(I want this part)', '']
>>> "lalala(I want this part)lalala".split("lalala")[1]
'(I want this part)'
>>>
import re
match = re.match('lalala(I want this part)lalala', 'lalalaI want this partlalala')
print match.group(1)
import re
string_to_check = "other_text...lalalaI want this partlalala...other_text"
p = re.compile("lalala(I want this part)lalala") # regex pattern
m = p.search(string_to_check) # use p.match if what you want is always at beginning of string
if m:
print m.group(1)
In trying to convert a Perl program to Python that parses function names out of modules, I ran into this problem, I received an error saying "group" was undefined. I soon realized that the exception was being thrown because p.match / p.search returns 0 if there is not a matching string.
Thus, the group operator cannot function on it. So, to avoid an exception, check if a match has been stored and then apply the group operator.
import re
filename = './file_to_parse.py'
p = re.compile('def (\w*)') # \w* greedily matches [a-zA-Z0-9_] character set
for each_line in open(filename,'r'):
m = p.match(each_line) # tries to match regex rule in p
if m:
m = m.group(1)
print m

Categories