Python: pythonic way to find last position in string that does not match regexIs there a way to run Python on Android?Finding the index of an item given a list containing it in PythonNicest way to pad zeroes to a stringDoes Python have a ternary conditional operator?How to substring a string in Python?Getting the last element of a list in PythonReverse a string in PythonDoes Python have a string 'contains' substring method?How do I lowercase a string in Python?Most elegant way to check if the string is empty in Python?

Question relating to a number theoretic function

Why the difference in metal between 銀行 and お金?

How to creep the reader out with what seems like a normal person?

Can someone publish a story that happened to you?

How come there are so many candidates for the 2020 Democratic party presidential nomination?

Why is current rating for multicore cable lower than single core with the same cross section?

Is there a way to get a compiler for the original B programming language?

TikZ how to make supply and demand arrows for nodes?

Stateful vs non-stateful app

How to verbalise code in Mathematica?

Minimum value of 4 digit number divided by sum of its digits

How to stop co-workers from teasing me because I know Russian?

What does KSP mean?

Who is the Umpire in this picture?

How would one muzzle a full grown polar bear in the 13th century?

Does this extra sentence in the description of the warlock's Eyes of the Rune Keeper eldritch invocation appear in any official reference?

How can I place the product on a social media post better?

Will tsunami waves travel forever if there was no land?

Single Colour Mastermind Problem

What's the polite way to say "I need to urinate"?

Sci-fi novel series with instant travel between planets through gates. A river runs through the gates

Executing a stored procedure which selects and inserts into tables in SQL Server

Any examples of headwear for races with animal ears?

Is thermodynamics only applicable to systems in equilibrium?



Python: pythonic way to find last position in string that does not match regex


Is there a way to run Python on Android?Finding the index of an item given a list containing it in PythonNicest way to pad zeroes to a stringDoes Python have a ternary conditional operator?How to substring a string in Python?Getting the last element of a list in PythonReverse a string in PythonDoes Python have a string 'contains' substring method?How do I lowercase a string in Python?Most elegant way to check if the string is empty in Python?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








6















In Python I try to find the last position in an arbitrary string that does not match a given pattern, which is specified as regex pattern (that includes the "not" in the match). For example, with the string uiae1iuae200, and the pattern of not being a number (regex pattern in Python for this would be [^0-9]), I would need '8' (the last 'e' before the '200') as result. What is the most pythonic way to achieve this?



As it's a little tricky to quickly find method documentation and the best suited method for something in the Python docs (due to method docs being somewhere in the middle of the corresponding page, like re.search() in the re page), the best way I quickly found myself is using re.search() - but the current form simply must be a suboptimal way of doing it:



import re
string = 'uiae1iuae200' # the string to investigate
len(string) - re.search(r'[^0-9]', string[::-1]).start()


I am not satisfied with this for two reasons: a) I need to reverse string before using it with [::-1], and b) I also need to reverse the resulting position (subtracting it from len(string) because of having reversed the string before. There needs to be better ways for this, likely even with the result of re.search().



I am aware of re.search(...).end() over .start(), but re.search() seems to split the results into groups, for which I did not quickly find a not-cumbersome way to apply it to the last matched group. Without specifying the group, .start(), .end(), etc, seem to always match the first group, which does not have the position information about the last match. However, selecting the group seems to at first require the return value to temporarily be saved in a variable (which prevents neat one-liners), as I would need to access both the information about selecting the last group and then to select .end() from this group.



What's your pythonic solution to this? I would value being pythonic more than having the most optimized runtime.



Update



The solution should be functional also in corner cases, like 123 (no position that matches the regex), empty string, etc. It should not crash e.g. because of selecting the last index of an empty list. However, as even my ugly answer above in the question would need more than one line for this, I guess a one-liner might be impossible for this (simply because one needs to check the return value of re.search() or re.finditer() before handling it). I'll accept pythonic multi-line solutions to this answer for this reason.










share|improve this question
























  • last position that does 'not' or does match regex? Last e matches [^0-9] pattern.

    – dgumo
    2 hours ago











  • Last position that does not match a certain pattern, like being a number. For numbers this would be [^0-9]. I'll update the question.

    – geekoverdose
    1 hour ago











  • Should s = 'uiae1iuae200aaaaaaaa' return the index of last char before a digit aka e (8) or the last char aka a (19)?

    – ruohola
    1 hour ago







  • 1





    With uiae1iuae200aaaaaaaa it should return the last position in the string, means 19.

    – geekoverdose
    1 hour ago


















6















In Python I try to find the last position in an arbitrary string that does not match a given pattern, which is specified as regex pattern (that includes the "not" in the match). For example, with the string uiae1iuae200, and the pattern of not being a number (regex pattern in Python for this would be [^0-9]), I would need '8' (the last 'e' before the '200') as result. What is the most pythonic way to achieve this?



As it's a little tricky to quickly find method documentation and the best suited method for something in the Python docs (due to method docs being somewhere in the middle of the corresponding page, like re.search() in the re page), the best way I quickly found myself is using re.search() - but the current form simply must be a suboptimal way of doing it:



import re
string = 'uiae1iuae200' # the string to investigate
len(string) - re.search(r'[^0-9]', string[::-1]).start()


I am not satisfied with this for two reasons: a) I need to reverse string before using it with [::-1], and b) I also need to reverse the resulting position (subtracting it from len(string) because of having reversed the string before. There needs to be better ways for this, likely even with the result of re.search().



I am aware of re.search(...).end() over .start(), but re.search() seems to split the results into groups, for which I did not quickly find a not-cumbersome way to apply it to the last matched group. Without specifying the group, .start(), .end(), etc, seem to always match the first group, which does not have the position information about the last match. However, selecting the group seems to at first require the return value to temporarily be saved in a variable (which prevents neat one-liners), as I would need to access both the information about selecting the last group and then to select .end() from this group.



What's your pythonic solution to this? I would value being pythonic more than having the most optimized runtime.



Update



The solution should be functional also in corner cases, like 123 (no position that matches the regex), empty string, etc. It should not crash e.g. because of selecting the last index of an empty list. However, as even my ugly answer above in the question would need more than one line for this, I guess a one-liner might be impossible for this (simply because one needs to check the return value of re.search() or re.finditer() before handling it). I'll accept pythonic multi-line solutions to this answer for this reason.










share|improve this question
























  • last position that does 'not' or does match regex? Last e matches [^0-9] pattern.

    – dgumo
    2 hours ago











  • Last position that does not match a certain pattern, like being a number. For numbers this would be [^0-9]. I'll update the question.

    – geekoverdose
    1 hour ago











  • Should s = 'uiae1iuae200aaaaaaaa' return the index of last char before a digit aka e (8) or the last char aka a (19)?

    – ruohola
    1 hour ago







  • 1





    With uiae1iuae200aaaaaaaa it should return the last position in the string, means 19.

    – geekoverdose
    1 hour ago














6












6








6


1






In Python I try to find the last position in an arbitrary string that does not match a given pattern, which is specified as regex pattern (that includes the "not" in the match). For example, with the string uiae1iuae200, and the pattern of not being a number (regex pattern in Python for this would be [^0-9]), I would need '8' (the last 'e' before the '200') as result. What is the most pythonic way to achieve this?



As it's a little tricky to quickly find method documentation and the best suited method for something in the Python docs (due to method docs being somewhere in the middle of the corresponding page, like re.search() in the re page), the best way I quickly found myself is using re.search() - but the current form simply must be a suboptimal way of doing it:



import re
string = 'uiae1iuae200' # the string to investigate
len(string) - re.search(r'[^0-9]', string[::-1]).start()


I am not satisfied with this for two reasons: a) I need to reverse string before using it with [::-1], and b) I also need to reverse the resulting position (subtracting it from len(string) because of having reversed the string before. There needs to be better ways for this, likely even with the result of re.search().



I am aware of re.search(...).end() over .start(), but re.search() seems to split the results into groups, for which I did not quickly find a not-cumbersome way to apply it to the last matched group. Without specifying the group, .start(), .end(), etc, seem to always match the first group, which does not have the position information about the last match. However, selecting the group seems to at first require the return value to temporarily be saved in a variable (which prevents neat one-liners), as I would need to access both the information about selecting the last group and then to select .end() from this group.



What's your pythonic solution to this? I would value being pythonic more than having the most optimized runtime.



Update



The solution should be functional also in corner cases, like 123 (no position that matches the regex), empty string, etc. It should not crash e.g. because of selecting the last index of an empty list. However, as even my ugly answer above in the question would need more than one line for this, I guess a one-liner might be impossible for this (simply because one needs to check the return value of re.search() or re.finditer() before handling it). I'll accept pythonic multi-line solutions to this answer for this reason.










share|improve this question
















In Python I try to find the last position in an arbitrary string that does not match a given pattern, which is specified as regex pattern (that includes the "not" in the match). For example, with the string uiae1iuae200, and the pattern of not being a number (regex pattern in Python for this would be [^0-9]), I would need '8' (the last 'e' before the '200') as result. What is the most pythonic way to achieve this?



As it's a little tricky to quickly find method documentation and the best suited method for something in the Python docs (due to method docs being somewhere in the middle of the corresponding page, like re.search() in the re page), the best way I quickly found myself is using re.search() - but the current form simply must be a suboptimal way of doing it:



import re
string = 'uiae1iuae200' # the string to investigate
len(string) - re.search(r'[^0-9]', string[::-1]).start()


I am not satisfied with this for two reasons: a) I need to reverse string before using it with [::-1], and b) I also need to reverse the resulting position (subtracting it from len(string) because of having reversed the string before. There needs to be better ways for this, likely even with the result of re.search().



I am aware of re.search(...).end() over .start(), but re.search() seems to split the results into groups, for which I did not quickly find a not-cumbersome way to apply it to the last matched group. Without specifying the group, .start(), .end(), etc, seem to always match the first group, which does not have the position information about the last match. However, selecting the group seems to at first require the return value to temporarily be saved in a variable (which prevents neat one-liners), as I would need to access both the information about selecting the last group and then to select .end() from this group.



What's your pythonic solution to this? I would value being pythonic more than having the most optimized runtime.



Update



The solution should be functional also in corner cases, like 123 (no position that matches the regex), empty string, etc. It should not crash e.g. because of selecting the last index of an empty list. However, as even my ugly answer above in the question would need more than one line for this, I guess a one-liner might be impossible for this (simply because one needs to check the return value of re.search() or re.finditer() before handling it). I'll accept pythonic multi-line solutions to this answer for this reason.







python regex string regex-negation






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago







geekoverdose

















asked 2 hours ago









geekoverdosegeekoverdose

727615




727615












  • last position that does 'not' or does match regex? Last e matches [^0-9] pattern.

    – dgumo
    2 hours ago











  • Last position that does not match a certain pattern, like being a number. For numbers this would be [^0-9]. I'll update the question.

    – geekoverdose
    1 hour ago











  • Should s = 'uiae1iuae200aaaaaaaa' return the index of last char before a digit aka e (8) or the last char aka a (19)?

    – ruohola
    1 hour ago







  • 1





    With uiae1iuae200aaaaaaaa it should return the last position in the string, means 19.

    – geekoverdose
    1 hour ago


















  • last position that does 'not' or does match regex? Last e matches [^0-9] pattern.

    – dgumo
    2 hours ago











  • Last position that does not match a certain pattern, like being a number. For numbers this would be [^0-9]. I'll update the question.

    – geekoverdose
    1 hour ago











  • Should s = 'uiae1iuae200aaaaaaaa' return the index of last char before a digit aka e (8) or the last char aka a (19)?

    – ruohola
    1 hour ago







  • 1





    With uiae1iuae200aaaaaaaa it should return the last position in the string, means 19.

    – geekoverdose
    1 hour ago

















last position that does 'not' or does match regex? Last e matches [^0-9] pattern.

– dgumo
2 hours ago





last position that does 'not' or does match regex? Last e matches [^0-9] pattern.

– dgumo
2 hours ago













Last position that does not match a certain pattern, like being a number. For numbers this would be [^0-9]. I'll update the question.

– geekoverdose
1 hour ago





Last position that does not match a certain pattern, like being a number. For numbers this would be [^0-9]. I'll update the question.

– geekoverdose
1 hour ago













Should s = 'uiae1iuae200aaaaaaaa' return the index of last char before a digit aka e (8) or the last char aka a (19)?

– ruohola
1 hour ago






Should s = 'uiae1iuae200aaaaaaaa' return the index of last char before a digit aka e (8) or the last char aka a (19)?

– ruohola
1 hour ago





1




1





With uiae1iuae200aaaaaaaa it should return the last position in the string, means 19.

– geekoverdose
1 hour ago






With uiae1iuae200aaaaaaaa it should return the last position in the string, means 19.

– geekoverdose
1 hour ago













3 Answers
3






active

oldest

votes


















4














This is a really pythonic way, which works perfectly with the new requirement:

(printing None with no errors when string = '123')



import re

string = 'uiae1iuae200'
ls = list(re.finditer(r'[^0-9]', string))
print(ls[-1].start() if ls else None)



Output:



8



Or alternatively using collections.deque:



import re
from collections import deque

string = 'uiae1iuae200'
que = deque(re.finditer(r'[^0-9]', string), maxlen=1)
print(que.pop().start() if que else None)



Output:



8






share|improve this answer




















  • 1





    This goes towards what I am aiming for. Will test it when I have time!

    – geekoverdose
    1 hour ago











  • Is there a one-liner solution to this? Python's iterators are not subscriptable, which prevents a [-1] index access in your solution. That I need a temporary variable and two lines of code as a result is a downside for me.

    – geekoverdose
    1 hour ago











  • The second "solution" stores the intermediate results in memory, which is certainly not something that you want as a tradeoff with a oneliner

    – Right leg
    1 hour ago






  • 1





    @Rightleg True, but OP said I would value being pythonic more than having the most optimized runtime., so I don't think he'll need to do this to a huge string.

    – ruohola
    38 mins ago











  • @geekoverdose Added new solutions which answer your updated requirements :)

    – ruohola
    38 mins ago


















2














You can use re.finditer to extract start positions of all matches and return the last one from list. Try this Python code (apologies if it is non-Pythonic as I am quite new to Python),



import re
print([m.start(0) for m in re.finditer(r'D', 'uiae1iuae200')][-1])


Prints,



8





share|improve this answer




















  • 1





    Nice answer, edited it a bit to remove unnecessary index shifting.

    – ruohola
    1 hour ago












  • @ruohola: Many thanks for improving my answer. Logically I had the idea but not exactly how to do it as new to Python. I appreciate.

    – Pushpesh Kumar Rajwanshi
    1 hour ago






  • 1





    Upside: one-liner possible (move the [-1] one line up). Downside: list comprehension required. Still a very good take on my question I guess!

    – geekoverdose
    1 hour ago











  • This will throw an IndexError on the new requirement case string = '123'.

    – ruohola
    10 mins ago


















0














This does not look Pythonic because it's not a one-liner, and it uses range(len(foo)), but it's pretty straightforward and probably not too inefficient.



def last_match(pattern, string):
for i in range(1, len(string) + 1):
substring = string[-i:]
if re.match(pattern, substring):
return len(string) - i


The idea is to iterate over the suffixes of string from the shortest to the longest, and to check if it matches pattern.



Since we're checking from the end, we know for sure that the first substring we meet that matches the pattern is the last.






share|improve this answer


















  • 2





    This is just not pythonic at all.

    – ruohola
    1 hour ago











  • I've come up with something similar to this, but I am not satisfied with its structure. A pythonic one-liner that is easily understand- and maintainable would be preferred. If this really is one of the most pythonic ways to achieve my goal, then I feel like filing a bug report with Python for this.

    – geekoverdose
    1 hour ago












  • @ruohola I'm interested to hear your criteria.

    – Right leg
    1 hour ago






  • 1





    This is not very readable, uses the range(len(foo)) antipattern, is quite a lot of lines etc. It's a valid solution, but when OP asked specifically for a 'pythonic' solution, I don't feel like this cuts it.

    – ruohola
    1 hour ago






  • 1





    I think you guys are confusing what pythonic is. Zen of python: "Readability counts." A crunched one liner doesn't mean its pythonic.

    – Julian Camilleri
    1 hour ago











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55890245%2fpython-pythonic-way-to-find-last-position-in-string-that-does-not-match-regex%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














This is a really pythonic way, which works perfectly with the new requirement:

(printing None with no errors when string = '123')



import re

string = 'uiae1iuae200'
ls = list(re.finditer(r'[^0-9]', string))
print(ls[-1].start() if ls else None)



Output:



8



Or alternatively using collections.deque:



import re
from collections import deque

string = 'uiae1iuae200'
que = deque(re.finditer(r'[^0-9]', string), maxlen=1)
print(que.pop().start() if que else None)



Output:



8






share|improve this answer




















  • 1





    This goes towards what I am aiming for. Will test it when I have time!

    – geekoverdose
    1 hour ago











  • Is there a one-liner solution to this? Python's iterators are not subscriptable, which prevents a [-1] index access in your solution. That I need a temporary variable and two lines of code as a result is a downside for me.

    – geekoverdose
    1 hour ago











  • The second "solution" stores the intermediate results in memory, which is certainly not something that you want as a tradeoff with a oneliner

    – Right leg
    1 hour ago






  • 1





    @Rightleg True, but OP said I would value being pythonic more than having the most optimized runtime., so I don't think he'll need to do this to a huge string.

    – ruohola
    38 mins ago











  • @geekoverdose Added new solutions which answer your updated requirements :)

    – ruohola
    38 mins ago















4














This is a really pythonic way, which works perfectly with the new requirement:

(printing None with no errors when string = '123')



import re

string = 'uiae1iuae200'
ls = list(re.finditer(r'[^0-9]', string))
print(ls[-1].start() if ls else None)



Output:



8



Or alternatively using collections.deque:



import re
from collections import deque

string = 'uiae1iuae200'
que = deque(re.finditer(r'[^0-9]', string), maxlen=1)
print(que.pop().start() if que else None)



Output:



8






share|improve this answer




















  • 1





    This goes towards what I am aiming for. Will test it when I have time!

    – geekoverdose
    1 hour ago











  • Is there a one-liner solution to this? Python's iterators are not subscriptable, which prevents a [-1] index access in your solution. That I need a temporary variable and two lines of code as a result is a downside for me.

    – geekoverdose
    1 hour ago











  • The second "solution" stores the intermediate results in memory, which is certainly not something that you want as a tradeoff with a oneliner

    – Right leg
    1 hour ago






  • 1





    @Rightleg True, but OP said I would value being pythonic more than having the most optimized runtime., so I don't think he'll need to do this to a huge string.

    – ruohola
    38 mins ago











  • @geekoverdose Added new solutions which answer your updated requirements :)

    – ruohola
    38 mins ago













4












4








4







This is a really pythonic way, which works perfectly with the new requirement:

(printing None with no errors when string = '123')



import re

string = 'uiae1iuae200'
ls = list(re.finditer(r'[^0-9]', string))
print(ls[-1].start() if ls else None)



Output:



8



Or alternatively using collections.deque:



import re
from collections import deque

string = 'uiae1iuae200'
que = deque(re.finditer(r'[^0-9]', string), maxlen=1)
print(que.pop().start() if que else None)



Output:



8






share|improve this answer















This is a really pythonic way, which works perfectly with the new requirement:

(printing None with no errors when string = '123')



import re

string = 'uiae1iuae200'
ls = list(re.finditer(r'[^0-9]', string))
print(ls[-1].start() if ls else None)



Output:



8



Or alternatively using collections.deque:



import re
from collections import deque

string = 'uiae1iuae200'
que = deque(re.finditer(r'[^0-9]', string), maxlen=1)
print(que.pop().start() if que else None)



Output:



8







share|improve this answer














share|improve this answer



share|improve this answer








edited 8 mins ago

























answered 2 hours ago









ruoholaruohola

2,129424




2,129424







  • 1





    This goes towards what I am aiming for. Will test it when I have time!

    – geekoverdose
    1 hour ago











  • Is there a one-liner solution to this? Python's iterators are not subscriptable, which prevents a [-1] index access in your solution. That I need a temporary variable and two lines of code as a result is a downside for me.

    – geekoverdose
    1 hour ago











  • The second "solution" stores the intermediate results in memory, which is certainly not something that you want as a tradeoff with a oneliner

    – Right leg
    1 hour ago






  • 1





    @Rightleg True, but OP said I would value being pythonic more than having the most optimized runtime., so I don't think he'll need to do this to a huge string.

    – ruohola
    38 mins ago











  • @geekoverdose Added new solutions which answer your updated requirements :)

    – ruohola
    38 mins ago












  • 1





    This goes towards what I am aiming for. Will test it when I have time!

    – geekoverdose
    1 hour ago











  • Is there a one-liner solution to this? Python's iterators are not subscriptable, which prevents a [-1] index access in your solution. That I need a temporary variable and two lines of code as a result is a downside for me.

    – geekoverdose
    1 hour ago











  • The second "solution" stores the intermediate results in memory, which is certainly not something that you want as a tradeoff with a oneliner

    – Right leg
    1 hour ago






  • 1





    @Rightleg True, but OP said I would value being pythonic more than having the most optimized runtime., so I don't think he'll need to do this to a huge string.

    – ruohola
    38 mins ago











  • @geekoverdose Added new solutions which answer your updated requirements :)

    – ruohola
    38 mins ago







1




1





This goes towards what I am aiming for. Will test it when I have time!

– geekoverdose
1 hour ago





This goes towards what I am aiming for. Will test it when I have time!

– geekoverdose
1 hour ago













Is there a one-liner solution to this? Python's iterators are not subscriptable, which prevents a [-1] index access in your solution. That I need a temporary variable and two lines of code as a result is a downside for me.

– geekoverdose
1 hour ago





Is there a one-liner solution to this? Python's iterators are not subscriptable, which prevents a [-1] index access in your solution. That I need a temporary variable and two lines of code as a result is a downside for me.

– geekoverdose
1 hour ago













The second "solution" stores the intermediate results in memory, which is certainly not something that you want as a tradeoff with a oneliner

– Right leg
1 hour ago





The second "solution" stores the intermediate results in memory, which is certainly not something that you want as a tradeoff with a oneliner

– Right leg
1 hour ago




1




1





@Rightleg True, but OP said I would value being pythonic more than having the most optimized runtime., so I don't think he'll need to do this to a huge string.

– ruohola
38 mins ago





@Rightleg True, but OP said I would value being pythonic more than having the most optimized runtime., so I don't think he'll need to do this to a huge string.

– ruohola
38 mins ago













@geekoverdose Added new solutions which answer your updated requirements :)

– ruohola
38 mins ago





@geekoverdose Added new solutions which answer your updated requirements :)

– ruohola
38 mins ago













2














You can use re.finditer to extract start positions of all matches and return the last one from list. Try this Python code (apologies if it is non-Pythonic as I am quite new to Python),



import re
print([m.start(0) for m in re.finditer(r'D', 'uiae1iuae200')][-1])


Prints,



8





share|improve this answer




















  • 1





    Nice answer, edited it a bit to remove unnecessary index shifting.

    – ruohola
    1 hour ago












  • @ruohola: Many thanks for improving my answer. Logically I had the idea but not exactly how to do it as new to Python. I appreciate.

    – Pushpesh Kumar Rajwanshi
    1 hour ago






  • 1





    Upside: one-liner possible (move the [-1] one line up). Downside: list comprehension required. Still a very good take on my question I guess!

    – geekoverdose
    1 hour ago











  • This will throw an IndexError on the new requirement case string = '123'.

    – ruohola
    10 mins ago















2














You can use re.finditer to extract start positions of all matches and return the last one from list. Try this Python code (apologies if it is non-Pythonic as I am quite new to Python),



import re
print([m.start(0) for m in re.finditer(r'D', 'uiae1iuae200')][-1])


Prints,



8





share|improve this answer




















  • 1





    Nice answer, edited it a bit to remove unnecessary index shifting.

    – ruohola
    1 hour ago












  • @ruohola: Many thanks for improving my answer. Logically I had the idea but not exactly how to do it as new to Python. I appreciate.

    – Pushpesh Kumar Rajwanshi
    1 hour ago






  • 1





    Upside: one-liner possible (move the [-1] one line up). Downside: list comprehension required. Still a very good take on my question I guess!

    – geekoverdose
    1 hour ago











  • This will throw an IndexError on the new requirement case string = '123'.

    – ruohola
    10 mins ago













2












2








2







You can use re.finditer to extract start positions of all matches and return the last one from list. Try this Python code (apologies if it is non-Pythonic as I am quite new to Python),



import re
print([m.start(0) for m in re.finditer(r'D', 'uiae1iuae200')][-1])


Prints,



8





share|improve this answer















You can use re.finditer to extract start positions of all matches and return the last one from list. Try this Python code (apologies if it is non-Pythonic as I am quite new to Python),



import re
print([m.start(0) for m in re.finditer(r'D', 'uiae1iuae200')][-1])


Prints,



8






share|improve this answer














share|improve this answer



share|improve this answer








edited 1 hour ago

























answered 2 hours ago









Pushpesh Kumar RajwanshiPushpesh Kumar Rajwanshi

13.7k21331




13.7k21331







  • 1





    Nice answer, edited it a bit to remove unnecessary index shifting.

    – ruohola
    1 hour ago












  • @ruohola: Many thanks for improving my answer. Logically I had the idea but not exactly how to do it as new to Python. I appreciate.

    – Pushpesh Kumar Rajwanshi
    1 hour ago






  • 1





    Upside: one-liner possible (move the [-1] one line up). Downside: list comprehension required. Still a very good take on my question I guess!

    – geekoverdose
    1 hour ago











  • This will throw an IndexError on the new requirement case string = '123'.

    – ruohola
    10 mins ago












  • 1





    Nice answer, edited it a bit to remove unnecessary index shifting.

    – ruohola
    1 hour ago












  • @ruohola: Many thanks for improving my answer. Logically I had the idea but not exactly how to do it as new to Python. I appreciate.

    – Pushpesh Kumar Rajwanshi
    1 hour ago






  • 1





    Upside: one-liner possible (move the [-1] one line up). Downside: list comprehension required. Still a very good take on my question I guess!

    – geekoverdose
    1 hour ago











  • This will throw an IndexError on the new requirement case string = '123'.

    – ruohola
    10 mins ago







1




1





Nice answer, edited it a bit to remove unnecessary index shifting.

– ruohola
1 hour ago






Nice answer, edited it a bit to remove unnecessary index shifting.

– ruohola
1 hour ago














@ruohola: Many thanks for improving my answer. Logically I had the idea but not exactly how to do it as new to Python. I appreciate.

– Pushpesh Kumar Rajwanshi
1 hour ago





@ruohola: Many thanks for improving my answer. Logically I had the idea but not exactly how to do it as new to Python. I appreciate.

– Pushpesh Kumar Rajwanshi
1 hour ago




1




1





Upside: one-liner possible (move the [-1] one line up). Downside: list comprehension required. Still a very good take on my question I guess!

– geekoverdose
1 hour ago





Upside: one-liner possible (move the [-1] one line up). Downside: list comprehension required. Still a very good take on my question I guess!

– geekoverdose
1 hour ago













This will throw an IndexError on the new requirement case string = '123'.

– ruohola
10 mins ago





This will throw an IndexError on the new requirement case string = '123'.

– ruohola
10 mins ago











0














This does not look Pythonic because it's not a one-liner, and it uses range(len(foo)), but it's pretty straightforward and probably not too inefficient.



def last_match(pattern, string):
for i in range(1, len(string) + 1):
substring = string[-i:]
if re.match(pattern, substring):
return len(string) - i


The idea is to iterate over the suffixes of string from the shortest to the longest, and to check if it matches pattern.



Since we're checking from the end, we know for sure that the first substring we meet that matches the pattern is the last.






share|improve this answer


















  • 2





    This is just not pythonic at all.

    – ruohola
    1 hour ago











  • I've come up with something similar to this, but I am not satisfied with its structure. A pythonic one-liner that is easily understand- and maintainable would be preferred. If this really is one of the most pythonic ways to achieve my goal, then I feel like filing a bug report with Python for this.

    – geekoverdose
    1 hour ago












  • @ruohola I'm interested to hear your criteria.

    – Right leg
    1 hour ago






  • 1





    This is not very readable, uses the range(len(foo)) antipattern, is quite a lot of lines etc. It's a valid solution, but when OP asked specifically for a 'pythonic' solution, I don't feel like this cuts it.

    – ruohola
    1 hour ago






  • 1





    I think you guys are confusing what pythonic is. Zen of python: "Readability counts." A crunched one liner doesn't mean its pythonic.

    – Julian Camilleri
    1 hour ago















0














This does not look Pythonic because it's not a one-liner, and it uses range(len(foo)), but it's pretty straightforward and probably not too inefficient.



def last_match(pattern, string):
for i in range(1, len(string) + 1):
substring = string[-i:]
if re.match(pattern, substring):
return len(string) - i


The idea is to iterate over the suffixes of string from the shortest to the longest, and to check if it matches pattern.



Since we're checking from the end, we know for sure that the first substring we meet that matches the pattern is the last.






share|improve this answer


















  • 2





    This is just not pythonic at all.

    – ruohola
    1 hour ago











  • I've come up with something similar to this, but I am not satisfied with its structure. A pythonic one-liner that is easily understand- and maintainable would be preferred. If this really is one of the most pythonic ways to achieve my goal, then I feel like filing a bug report with Python for this.

    – geekoverdose
    1 hour ago












  • @ruohola I'm interested to hear your criteria.

    – Right leg
    1 hour ago






  • 1





    This is not very readable, uses the range(len(foo)) antipattern, is quite a lot of lines etc. It's a valid solution, but when OP asked specifically for a 'pythonic' solution, I don't feel like this cuts it.

    – ruohola
    1 hour ago






  • 1





    I think you guys are confusing what pythonic is. Zen of python: "Readability counts." A crunched one liner doesn't mean its pythonic.

    – Julian Camilleri
    1 hour ago













0












0








0







This does not look Pythonic because it's not a one-liner, and it uses range(len(foo)), but it's pretty straightforward and probably not too inefficient.



def last_match(pattern, string):
for i in range(1, len(string) + 1):
substring = string[-i:]
if re.match(pattern, substring):
return len(string) - i


The idea is to iterate over the suffixes of string from the shortest to the longest, and to check if it matches pattern.



Since we're checking from the end, we know for sure that the first substring we meet that matches the pattern is the last.






share|improve this answer













This does not look Pythonic because it's not a one-liner, and it uses range(len(foo)), but it's pretty straightforward and probably not too inefficient.



def last_match(pattern, string):
for i in range(1, len(string) + 1):
substring = string[-i:]
if re.match(pattern, substring):
return len(string) - i


The idea is to iterate over the suffixes of string from the shortest to the longest, and to check if it matches pattern.



Since we're checking from the end, we know for sure that the first substring we meet that matches the pattern is the last.







share|improve this answer












share|improve this answer



share|improve this answer










answered 2 hours ago









Right legRight leg

8,70442450




8,70442450







  • 2





    This is just not pythonic at all.

    – ruohola
    1 hour ago











  • I've come up with something similar to this, but I am not satisfied with its structure. A pythonic one-liner that is easily understand- and maintainable would be preferred. If this really is one of the most pythonic ways to achieve my goal, then I feel like filing a bug report with Python for this.

    – geekoverdose
    1 hour ago












  • @ruohola I'm interested to hear your criteria.

    – Right leg
    1 hour ago






  • 1





    This is not very readable, uses the range(len(foo)) antipattern, is quite a lot of lines etc. It's a valid solution, but when OP asked specifically for a 'pythonic' solution, I don't feel like this cuts it.

    – ruohola
    1 hour ago






  • 1





    I think you guys are confusing what pythonic is. Zen of python: "Readability counts." A crunched one liner doesn't mean its pythonic.

    – Julian Camilleri
    1 hour ago












  • 2





    This is just not pythonic at all.

    – ruohola
    1 hour ago











  • I've come up with something similar to this, but I am not satisfied with its structure. A pythonic one-liner that is easily understand- and maintainable would be preferred. If this really is one of the most pythonic ways to achieve my goal, then I feel like filing a bug report with Python for this.

    – geekoverdose
    1 hour ago












  • @ruohola I'm interested to hear your criteria.

    – Right leg
    1 hour ago






  • 1





    This is not very readable, uses the range(len(foo)) antipattern, is quite a lot of lines etc. It's a valid solution, but when OP asked specifically for a 'pythonic' solution, I don't feel like this cuts it.

    – ruohola
    1 hour ago






  • 1





    I think you guys are confusing what pythonic is. Zen of python: "Readability counts." A crunched one liner doesn't mean its pythonic.

    – Julian Camilleri
    1 hour ago







2




2





This is just not pythonic at all.

– ruohola
1 hour ago





This is just not pythonic at all.

– ruohola
1 hour ago













I've come up with something similar to this, but I am not satisfied with its structure. A pythonic one-liner that is easily understand- and maintainable would be preferred. If this really is one of the most pythonic ways to achieve my goal, then I feel like filing a bug report with Python for this.

– geekoverdose
1 hour ago






I've come up with something similar to this, but I am not satisfied with its structure. A pythonic one-liner that is easily understand- and maintainable would be preferred. If this really is one of the most pythonic ways to achieve my goal, then I feel like filing a bug report with Python for this.

– geekoverdose
1 hour ago














@ruohola I'm interested to hear your criteria.

– Right leg
1 hour ago





@ruohola I'm interested to hear your criteria.

– Right leg
1 hour ago




1




1





This is not very readable, uses the range(len(foo)) antipattern, is quite a lot of lines etc. It's a valid solution, but when OP asked specifically for a 'pythonic' solution, I don't feel like this cuts it.

– ruohola
1 hour ago





This is not very readable, uses the range(len(foo)) antipattern, is quite a lot of lines etc. It's a valid solution, but when OP asked specifically for a 'pythonic' solution, I don't feel like this cuts it.

– ruohola
1 hour ago




1




1





I think you guys are confusing what pythonic is. Zen of python: "Readability counts." A crunched one liner doesn't mean its pythonic.

– Julian Camilleri
1 hour ago





I think you guys are confusing what pythonic is. Zen of python: "Readability counts." A crunched one liner doesn't mean its pythonic.

– Julian Camilleri
1 hour ago

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55890245%2fpython-pythonic-way-to-find-last-position-in-string-that-does-not-match-regex%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Are there any AGPL-style licences that require source code modifications to be public? Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?Force derivative works to be publicAre there any GPL like licenses for Apple App Store?Do you violate the GPL if you provide source code that cannot be compiled?GPL - is it distribution to use libraries in an appliance loaned to customers?Distributing App for free which uses GPL'ed codeModifications of server software under GPL, with web/CLI interfaceDoes using an AGPLv3-licensed library prevent me from dual-licensing my own source code?Can I publish only select code under GPLv3 from a private project?Is there published precedent regarding the scope of covered work that uses AGPL software?If MIT licensed code links to GPL licensed code what should be the license of the resulting binary program?If I use a public API endpoint that has its source code licensed under AGPL in my app, do I need to disclose my source?

2013 GY136 Descoberta | Órbita | Referências Menu de navegação«List Of Centaurs and Scattered-Disk Objects»«List of Known Trans-Neptunian Objects»

Metrô de Los Teques Índice Linhas | Estações | Ver também | Referências Ligações externas | Menu de navegação«INSTITUCIÓN»«Mapa de rutas»originalMetrô de Los TequesC.A. Metro Los Teques |Alcaldía de Guaicaipuro – Sitio OficialGobernacion de Mirandaeeeeeee