I have several strings in a list:
['~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_item2.png', '~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_item3.png', '~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_item4.png'
I need to remove the 'item2', 'item3', 'item4' so I can later replace with another variable that changes each time that I am passing in: variable = {changing item}
I have tried things like string.replace("item{i}.format(i) for i in range(20), "") or re.sub but I can't seem to get it to work - any suggestions?
I would expect the output [~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_{changing item1}.png, ~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_{changing item2}.png, ~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_{changing item3}.png]
You can use re.sub to replace string ('item<number>') like so:
re.sub(r'item\d+', var, x)
Code:
import re
lst = ['~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_item2.png', 'some/thing/0034_item5.png']
var = 'foo'
result = [re.sub(r'item\d+', var, x) for x in lst]
# ['~/tmp/GROUP-G07T01/items/GROUP-G07T01-000021_foo.png', 'some/thing/0034_foo.png']
Try using the re regex module. You need to use a valid regex. You can specify one or more characters 0 to 9 by using [0-9]+.
fixed_str = re.replace("item[0-9]+", "", input_str)
Here is the reference to how to format regexs:
https://docs.python.org/3/library/re.html
You can also use online sites such as regex101.com to experiment with regex formatting in real time to make sure it works ahead of time.
Related
I've seen a lot of examples on how to remove brackets from a string in Python, but I've not seen any that allow me to remove the brackets and a number inside of the brackets from that string.
For example, suppose I've got a string such as "abc[1]". How can I remove the "[1]" from the string to return just "abc"?
I've tried the following:
stringTest = "abc[1]"
stringTestWithoutBrackets = str(stringTest).strip('[]')
but this only outputs the string without the final bracket
abc[1
I've also tried with a wildcard option:
stringTest = "abc[1]"
stringTestWithoutBrackets = str(stringTest).strip('[\w+\]')
but this also outputs the string without the final bracket
abc[1
You could use regular expressions for that, but I think the easiest way would be to use split:
>>> stringTest = "abc[1][2][3]"
>>> stringTest.split('[', maxsplit=1)[0]
'abc'
You can use regex but you need to use it with the re module:
re.sub(r'\[\d+\]', '', stringTest)
If the [<number>] part is always at the end of the string you can also strip via:
stringTest.rstrip('[0123456789]')
Though the latter version might strip beyond the [ if the previous character is in the strip list too. For example in "abc1[5]" the "1" would be stripped as well.
Assuming your string has the format "text[number]" and you only want to keep the "text", then you could do:
stringTest = "abc[1]"
bracketBegin = stringTest.find('[')
stringTestWithoutBrackets = stringTest[:bracketBegin]
I have a String from which I want to take the values within the parenthesis. Then, get the values that are separated from a comma.
Example: x(142,1,23ERWA31)
I would like to get:
142
1
23ERWA31
Is it possible to get everything with one regex?
I have found a method to do so, but it is ugly.
This is how I did it in python:
import re
string = "x(142,1,23ERWA31)"
firstResult = re.search("\((.*?)\)", string)
secondResult = re.search("(?<=\()(.*?)(?=\))", firstResult.group(0))
finalResult = [x.strip() for x in secondResult.group(0).split(',')]
for i in finalResult:
print(i)
142
1
23ERWA31
This works for your example string:
import re
string = "x(142,1,23ERWA31)"
l = re.findall (r'([^(,)]+)(?!.*\()', string)
print (l)
Result: a plain list
['142', '1', '23ERWA31']
The expression matches a sequence of characters not in (,,,) and – to prevent the first x being picked up – may not be followed by a ( anywhere further in the string. This makes it also work if your preamble x consists of more than a single character.
findall rather than search makes sure all items are found, and as a bonus it returns a plain list of the results.
You can make this a lot simpler. You are running your first Regex but then not taking the result. You want .group(1) (inside the brackets), not .group(0) (the whole match). Once you have that you can just split it on ,:
import re
string = "x(142,1,23ERWA31)"
firstResult = re.search("\((.*?)\)", string)
for e in firstResult.group(1).split(','):
print(e)
A little wonky looking, and also assuming there's always going to be a grouping of 3 values in the parenthesis - but try this regex
\((.*?),(.*?),(.*?)\)
To extract all the group matches to a single object - your code would then look like
import re
string = "x(142,1,23ERWA31)"
firstResult = re.search("\((.*?),(.*?),(.*?)\)", string).groups()
You can then call the firstResult object like a list
>> print(firstResult[2])
23ERWA31
I am using the following pattern to clean a piece of text (replacing the matches with null):
{\s{\s\"[A-Za-z0-9.,\-:]*(?<!\bbecause\b)(?<!\bsince\b)\"\s}\s\"[A-Za-z0-9.,\-:]*\"\s}
I have a list of relators like "because" and "since" that could change every time. So I created a separate string which is a regex itself like:
lookahead_string = (?<!\bbecause\b)(?<!\bsince\b)
And put it in my original regex pattern and changed it like the following:
{\s{\s\"[A-Za-z0-9.,\-:]*'+lookahead_string+r'\"\s}\s\"[A-Za-z0-9.,\-:]*\"\s}
But the new pattern does not match the parts of the input text that could be matched using the original regex pattern. The code I am using is:
lookahead_string = ''
relators = ["because", "since"]
for rel in relators:
lookahead_string += '(?<!\b'+rel+'\b)'
text = re.sub(r'{\s{\s\"[A-Za-z0-9.,\-:]*'+lookahead_string+r'\"\s}\s\"[A-Za-z0-9.,\-:]*\"\s}', "", text)
text = ' '.join(text.split())
What should I do to make it work?! I have already tried using re.escape and format string but none of them works in my case.
Edit: I removed the input output text because I thought it is a little confusing. However, I thank #DYZ for the good suggestion.
A suggestion: Instead of messing up with the complex string syntax, convert the string to a Python list.
import ast
l = ast.literal_eval("[" + s.replace("}", "],").replace("{", "[") + "]")
#[[[[['I'], 'PRP'], 'NP'], [[[[['did'], 'VBD'], [['not'], 'RB'], 'VP'],
# ..., 'S'], '']
Now you can apply simple list functions to your data and, when done, transform the list to a bracketed string.
I have the following file names that exhibit this pattern:
000014_L_20111007T084734-20111008T023142.txt
000014_U_20111007T084734-20111008T023142.txt
...
I want to extract the middle two time stamp parts after the second underscore '_' and before '.txt'. So I used the following Python regex string split:
time_info = re.split('^[0-9]+_[LU]_|-|\.txt$', f)
But this gives me two extra empty strings in the returned list:
time_info=['', '20111007T084734', '20111008T023142', '']
How do I get only the two time stamp information? i.e. I want:
time_info=['20111007T084734', '20111008T023142']
I'm no Python expert but maybe you could just remove the empty strings from your list?
str_list = re.split('^[0-9]+_[LU]_|-|\.txt$', f)
time_info = filter(None, str_list)
Don't use re.split(), use the groups() method of regex Match/SRE_Match objects.
>>> f = '000014_L_20111007T084734-20111008T023142.txt'
>>> time_info = re.search(r'[LU]_(\w+)-(\w+)\.', f).groups()
>>> time_info
('20111007T084734', '20111008T023142')
You can even name the capturing groups and retrieve them in a dict, though you use groupdict() rather than groups() for that. (The regex pattern for such a case would be something like r'[LU]_(?P<groupA>\w+)-(?P<groupB>\w+)\.')
If the timestamps are always after the second _ then you can use str.split and str.strip:
>>> strs = "000014_L_20111007T084734-20111008T023142.txt"
>>> strs.strip(".txt").split("_",2)[-1].split("-")
['20111007T084734', '20111008T023142']
Since this came up on google and for completeness, try using re.findall as an alternative!
This does require a little re-thinking, but it still returns a list of matches like split does. This makes it a nice drop-in replacement for some existing code and gets rid of the unwanted text. Pair it with lookaheads and/or lookbehinds and you get very similar behavior.
Yes, this is a bit of a "you're asking the wrong question" answer and doesn't use re.split(). It does solve the underlying issue- your list of matches suddenly have zero-length strings in it and you don't want that.
>>> f='000014_L_20111007T084734-20111008T023142.txt'
>>> f[10:-4].split('-')
['0111007T084734', '20111008T023142']
or, somewhat more general:
>>> f[f.rfind('_')+1:-4].split('-')
['20111007T084734', '20111008T023142']
So from this string:
"name[id]"
I need this:
"id"
I used str.split ('[]'), but it didn't work. Does it only take a single delimiter?
Use a regular expression:
import re
s = "name[id]"
re.find(r"\[(.*?)\]", s).group(1) # = 'id'
str.split() takes a string on which to split input. For instance:
"i,split,on commas".split(',') # = ['i', 'split', 'on commas']
The re module also allows you to split by regular expression, which can be very useful, and I think is what you meant to do.
import re
s = "name[id]"
# split by either a '[' or a ']'
re.split('\[|\]', s) # = ['name', 'id', '']
Either
"name[id]".split('[')[1][:-1] == "id"
or
"name[id]".split('[')[1].split(']')[0] == "id"
or
re.search(r'\[(.*?)\]',"name[id]").group(1) == "id"
or
re.split(r'[\[\]]',"name[id]")[1] == "id"
Yes, the delimiter is the whole string argument passed to split. So your example would only split a string like 'name[]id[]'.
Try eg. something like:
'name[id]'.split('[', 1)[-1].split(']', 1)[0]
'name[id]'.split('[', 1)[-1].rstrip(']')
I'm not a fan of regex, but in cases like it often provides the best solution.
Triptych already recommended this, but I'd like to point out that the ?P<> group assignment can be used to assign a match to a dictionary key:
>>> m = re.match(r'.*\[(?P<id>\w+)\]', 'name[id]')
>>> result_dict = m.groupdict()
>>> result_dict
{'id': 'id'}
>>>
You don't actually need regular expressions for this. The .index() function and string slicing will work fine.
Say we have:
>>> s = 'name[id]'
Then:
>>> s[s.index('[')+1:s.index(']')]
'id'
To me, this is easy to read: "start one character after the [ and finish before the ]".
def between_brackets(text):
return text.partition('[')[2].partition(']')[0]
This will also work even if your string does not contain a […] construct, and it assumes an implied ] at the end in the case you have only a [ somewhere in the string.
I'm new to python and this is an old question, but maybe this?
str.split('[')[1].strip(']')
You can get the value of the list use []. For example, create a list from URL like below with split.
>>> urls = 'http://quotes.toscrape.com/page/1/'
This generates a list like the one below.
>>> print( urls.split("/") )
['http:', '', 'quotes.toscrape.com', 'page', '11', '']
And what if you wanna get value only "http" from this list? You can use like this
>>> print(urls.split("/")[0])
http:
Or what if you wanna get value only "1" from this list? You can use like this
>>> print(urls.split("/")[-2])
1
str.split uses the entire parameter to split a string. Try:
str.split("[")[1].split("]")[0]