Re: Spread a statement over various lines
Am 18.09.2019 um 22:24 schrieb Alexandre Brault: On 2019-09-18 4:01 p.m., Ralf M. wrote: I don't know the exact rules of Windows wildcards, so there may be even more cases of unexpected behavior. If anyone knows where to find the complete rules (or a python module that implements them), I would be interested. fnmatch in the standard library has a translate function that transforms a glob pattern to a regex https://docs.python.org/3.7/library/fnmatch.html#fnmatch.translate Alex Thank you for the pointer. However, from the documentation of module fnmatch: "This module provides support for Unix shell-style wildcards" And Unix shell-style wildcards differ from Windows cmd wildcards. For one, [ ] are special in Unix shells, but not in Windows cmd. For another, cmd wildcards have several quirks, e.g. *.* matching filenames that don't contain a dot, or "a???" matching "ab". Several years ago, when I needed DOS-style globbing, I copied fnmatch.py and glob.py from the standard library and modified them to treat [ ] as not special. However, that didn't help with the cmd quirks, and I don't even know all the rules about cmd wildcards. Ralf -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
Am 18.09.2019 um 22:22 schrieb Chris Angelico: On Thu, Sep 19, 2019 at 6:20 AM Ralf M. wrote: Am 17.09.2019 um 20:59 schrieb Manfred Lotz: I have a function like follows def regex_from_filepat(fpat): rfpat = fpat.replace('.', '\\.') \ .replace('%', '.') \ .replace('*', '.*') return '^' + rfpat + '$' As I don't want to have the replace() functions in one line my question is if it is ok to spread the statement over various lines as shown above, or if there is a better way? Thanks. Not related to your question, but: You seem to try to convert a Windows wildcard pattern to a regex pattern. However, wildcards sometimes behave a bit different than what you assume. I know for instance that *.* matches any filename, even if the filename doesn't contain a dot. Hmm, why do you assume it's a Windows wildcard pattern specifically? ChrisA I think I jumped to that conclusion because the example didn't treat [ ] as special characters. [ ] are special in a unix shell, but not at a cmd prompt. Thinking it over, [ ] would need a much differnt treatment and might be left out of the example for that reason, though. Also I may be biased: I mostly use Windows, Linux only occasionally. Ralf M. -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
Manfred Lotz wrote: >> Where does '%' come from? >> > > '%' was a mistake as I had replied myself to my initial question. Oh, sorry. I missed that. -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Thu, 19 Sep 2019 08:36:04 +0200 Peter Otten <__pete...@web.de> wrote: > Manfred Lotz wrote: > > >> Not related to your question, but: > >> You seem to try to convert a Windows wildcard pattern to a regex > >> pattern. > > > > No, I'm on Linux. > > > > Shortly, after I had posted the question I discovered fnmatch() in > > the standard library, and I changed my code accordingly. > > I would have pointed to fnmatch, but I didn't recognize the '%' that > you used instead of the usual '?', and fnmatch doesn't either, I > think. > > Where does '%' come from? > '%' was a mistake as I had replied myself to my initial question. -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
Manfred Lotz wrote: >> Not related to your question, but: >> You seem to try to convert a Windows wildcard pattern to a regex >> pattern. > > No, I'm on Linux. > > Shortly, after I had posted the question I discovered fnmatch() in the > standard library, and I changed my code accordingly. I would have pointed to fnmatch, but I didn't recognize the '%' that you used instead of the usual '?', and fnmatch doesn't either, I think. Where does '%' come from? -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Wed, 18 Sep 2019 22:01:34 +0200 "Ralf M." wrote: > Am 17.09.2019 um 20:59 schrieb Manfred Lotz: > > I have a function like follows > > > > def regex_from_filepat(fpat): > > rfpat = fpat.replace('.', '\\.') \ > >.replace('%', '.') \ > >.replace('*', '.*') > > > > return '^' + rfpat + '$' > > > > > > As I don't want to have the replace() functions in one line my > > question is if it is ok to spread the statement over various lines > > as shown above, or if there is a better way? > > > > Thanks. > > > > Not related to your question, but: > You seem to try to convert a Windows wildcard pattern to a regex > pattern. No, I'm on Linux. Shortly, after I had posted the question I discovered fnmatch() in the standard library, and I changed my code accordingly. Nevertheless, I was happy to have asked the question as the following discussion was very interesting for me. -- Manfred -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Wednesday, September 18, 2019 at 9:01:21 AM UTC-4, Manfred Lotz wrote: > On Wed, 18 Sep 2019 08:30:08 +0200 > Peter Otten <__pete...@web.de> wrote: > > > Manfred Lotz wrote: > > > > > I have a function like follows > > > > > > def regex_from_filepat(fpat): > > > rfpat = fpat.replace('.', '\\.') \ > > > .replace('%', '.') \ > > > .replace('*', '.*') > > > > > > return '^' + rfpat + '$' > > > > > > > > > As I don't want to have the replace() functions in one line my > > > question is if it is ok to spread the statement over various lines > > > as shown above, or if there is a better way? > > > > Sometimes you can avoid method-chaining: > > > > >>> REP = str.maketrans({".": "\\.", "%": ".", "*": ".*"}) > > >>> def regex_from_filepat(fpat): > > ... return fpat.translate(REP) > > ... > > >>> regex_from_filepat("*foo.%") > > '.*foo\\..' > > > > Very interesting. Thanks for this. While I think that str.translate() is the right tool for this job, here's another way to avoid line continuations (not necessarily better): def regex_from_filepat(fpat): replacements = [ ('.', '\\.'), ('%', '.'), ('*', '.*'), ] rfpat = fpat for old, new in replacements: rfpat = rfpat.replace(old, new) return '^' + rfpat + '$' -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On 2019-09-18 4:01 p.m., Ralf M. wrote: > Am 17.09.2019 um 20:59 schrieb Manfred Lotz: >> I have a function like follows >> >> def regex_from_filepat(fpat): >> rfpat = fpat.replace('.', '\\.') \ >> .replace('%', '.') \ >> .replace('*', '.*') >> >> return '^' + rfpat + '$' >> >> >> As I don't want to have the replace() functions in one line my >> question is if it is ok to spread the statement over various lines as >> shown above, or if there is a better way? >> >> Thanks. >> > > Not related to your question, but: > You seem to try to convert a Windows wildcard pattern to a regex > pattern. However, wildcards sometimes behave a bit different than what > you assume. I know for instance that *.* matches any filename, even if > the filename doesn't contain a dot. > > Out of curiosity I played around a bit, details below. > As you can see, there are other wildcard strangenesses, e.g. > - ? does not match a dot > - between letters etc. matches exactly 4 characters, but > at the end or directly before a dot matches at most 4 characters > > I don't know the exact rules of Windows wildcards, so there may be > even more cases of unexpected behavior. > If anyone knows where to find the complete rules (or a python module > that implements them), I would be interested. > fnmatch in the standard library has a translate function that transforms a glob pattern to a regex https://docs.python.org/3.7/library/fnmatch.html#fnmatch.translate Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Thu, Sep 19, 2019 at 6:20 AM Ralf M. wrote: > > Am 17.09.2019 um 20:59 schrieb Manfred Lotz: > > I have a function like follows > > > > def regex_from_filepat(fpat): > > rfpat = fpat.replace('.', '\\.') \ > >.replace('%', '.') \ > >.replace('*', '.*') > > > > return '^' + rfpat + '$' > > > > > > As I don't want to have the replace() functions in one line my > > question is if it is ok to spread the statement over various lines as > > shown above, or if there is a better way? > > > > Thanks. > > > > Not related to your question, but: > You seem to try to convert a Windows wildcard pattern to a regex > pattern. However, wildcards sometimes behave a bit different than what > you assume. I know for instance that *.* matches any filename, even if > the filename doesn't contain a dot. Hmm, why do you assume it's a Windows wildcard pattern specifically? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
Am 17.09.2019 um 20:59 schrieb Manfred Lotz: I have a function like follows def regex_from_filepat(fpat): rfpat = fpat.replace('.', '\\.') \ .replace('%', '.') \ .replace('*', '.*') return '^' + rfpat + '$' As I don't want to have the replace() functions in one line my question is if it is ok to spread the statement over various lines as shown above, or if there is a better way? Thanks. Not related to your question, but: You seem to try to convert a Windows wildcard pattern to a regex pattern. However, wildcards sometimes behave a bit different than what you assume. I know for instance that *.* matches any filename, even if the filename doesn't contain a dot. Out of curiosity I played around a bit, details below. As you can see, there are other wildcard strangenesses, e.g. - ? does not match a dot - between letters etc. matches exactly 4 characters, but at the end or directly before a dot matches at most 4 characters I don't know the exact rules of Windows wildcards, so there may be even more cases of unexpected behavior. If anyone knows where to find the complete rules (or a python module that implements them), I would be interested. Regards, Ralf - Details (Win 7 home SP1) - C:\tmp>more pydirb.py #!/usr/bin/env python3 import os, re, sys def regex_from_filepat(fpat): rfpat = fpat.replace('.', '\\.') \ .replace('?', '.') \ .replace('*', '.*') return '^' + rfpat + '$' regexfilepat = re.compile(regex_from_filepat(sys.argv[1])) for name in os.listdir(): if regexfilepat.match(name): print(name) C:\tmp>dir /b * foo foo.bar foo.bar.c foo.c pydirb.py C:\tmp>pydirb * foo foo.bar foo.bar.c foo.c pydirb.py C:\tmp>dir /b *.* foo foo.bar foo.bar.c foo.c pydirb.py C:\tmp>pydirb *.* foo.bar foo.bar.c foo.c pydirb.py C:\tmp>dir /b *.*.*.*.* foo foo.bar foo.bar.c foo.c pydirb.py C:\tmp>pydirb *.*.*.*.* C:\tmp>dir /b foo.? foo foo.c C:\tmp>pydirb foo.? foo.c C:\tmp>dir /b foo. foo foo.bar foo.c C:\tmp>pydirb foo. C:\tmp>dir /b foo?bar Datei nicht gefunden C:\tmp>pydirb foo?bar foo.bar C:\tmp>dir /b f?o.bar foo.bar C:\tmp>pydirb f?o.bar foo.bar C:\tmp>dir /b f??o.bar Datei nicht gefunden C:\tmp>pydirb f??o.bar C:\tmp>dir /b fo?.bar foo.bar C:\tmp>pydirb fo?.bar foo.bar C:\tmp>dir /b fo??.bar foo.bar C:\tmp>pydirb fo??.bar C:\tmp>dir /b foo??.bar foo.bar C:\tmp>pydirb foo??.bar -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Wed, 18 Sep 2019 08:30:08 +0200 Peter Otten <__pete...@web.de> wrote: > Manfred Lotz wrote: > > > I have a function like follows > > > > def regex_from_filepat(fpat): > > rfpat = fpat.replace('.', '\\.') \ > > .replace('%', '.') \ > > .replace('*', '.*') > > > > return '^' + rfpat + '$' > > > > > > As I don't want to have the replace() functions in one line my > > question is if it is ok to spread the statement over various lines > > as shown above, or if there is a better way? > > Sometimes you can avoid method-chaining: > > >>> REP = str.maketrans({".": "\\.", "%": ".", "*": ".*"}) > >>> def regex_from_filepat(fpat): > ... return fpat.translate(REP) > ... > >>> regex_from_filepat("*foo.%") > '.*foo\\..' > Very interesting. Thanks for this. > Generally speaking a long statement may be a hint that there is an > alternative spelling. > > I'll keep it in my mind. -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Wed, 18 Sep 2019 09:52:21 +0200 Wolfgang Maier wrote: > On 17.09.19 20:59, Manfred Lotz wrote: > > I have a function like follows > > > > def regex_from_filepat(fpat): > > rfpat = fpat.replace('.', '\\.') \ > > .replace('%', '.') \ > > .replace('*', '.*') > > > > return '^' + rfpat + '$' > > > > > > As I don't want to have the replace() functions in one line my > > question is if it is ok to spread the statement over various lines > > as shown above, or if there is a better way? > > > > One problem with explicit line continuation using \ is that it is > dependent on the backslash being the last character on the line, i.e. > a single space at the end of the line will result in a SyntaxError. > This is why implicit line continuation relying on opened parentheses, > brackets or curly braces is often preferred, and recommended over > backslash continuation in PEP8 > (https://www.python.org/dev/peps/pep-0008/#maximum-line-length). > To use implicit line continuation you could either introduce extra > surrounding parentheses as suggested by others, or you may make use > of the parentheses you have already, like so: > > def regex_from_filepat(fpat): > rfpat = fpat.replace( > '.', '\\.' > ).replace( > '%', '.' > ).replace( > '*', '.*' > ) > > return '^' + rfpat + '$' > > Thanks for showing. Good to be aware of this possiblity. So, it seems it doesn't hurt to read PEP8. -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On 17.09.19 20:59, Manfred Lotz wrote: > I have a function like follows > > def regex_from_filepat(fpat): > rfpat = fpat.replace('.', '\\.') \ > .replace('%', '.') \ > .replace('*', '.*') > > return '^' + rfpat + '$' > > > As I don't want to have the replace() functions in one line my > question is if it is ok to spread the statement over various lines as > shown above, or if there is a better way? > One problem with explicit line continuation using \ is that it is dependent on the backslash being the last character on the line, i.e. a single space at the end of the line will result in a SyntaxError. This is why implicit line continuation relying on opened parentheses, brackets or curly braces is often preferred, and recommended over backslash continuation in PEP8 (https://www.python.org/dev/peps/pep-0008/#maximum-line-length). To use implicit line continuation you could either introduce extra surrounding parentheses as suggested by others, or you may make use of the parentheses you have already, like so: def regex_from_filepat(fpat): rfpat = fpat.replace( '.', '\\.' ).replace( '%', '.' ).replace( '*', '.*' ) return '^' + rfpat + '$' -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
Manfred Lotz wrote: > I have a function like follows > > def regex_from_filepat(fpat): > rfpat = fpat.replace('.', '\\.') \ > .replace('%', '.') \ > .replace('*', '.*') > > return '^' + rfpat + '$' > > > As I don't want to have the replace() functions in one line my > question is if it is ok to spread the statement over various lines as > shown above, or if there is a better way? Sometimes you can avoid method-chaining: >>> REP = str.maketrans({".": "\\.", "%": ".", "*": ".*"}) >>> def regex_from_filepat(fpat): ... return fpat.translate(REP) ... >>> regex_from_filepat("*foo.%") '.*foo\\..' Generally speaking a long statement may be a hint that there is an alternative spelling. -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Tue, 17 Sep 2019 16:51:04 -0400 Dan Sommers <2qdxy4rzwzuui...@potatochowder.com> wrote: > On 9/17/19 2:59 PM, Manfred Lotz wrote: > > > def regex_from_filepat(fpat): > > rfpat = fpat.replace('.', '\\.') \ > >.replace('%', '.') \ > >.replace('*', '.*') > > > > return '^' + rfpat + '$' > > > > As I don't want to have the replace() functions in one line my > > question is if it is ok to spread the statement over various lines > > as shown above, or if there is a better way? > > Is that way okay? Sure. Are there other ways? Sure. > > To isolate each replace() function on its own line, and to eliminate > the clutter of the backslashes, consider this: > > rfpat = (fpat >.replace('.', '\\.') >.replace('%', '.') >.replace('*', '.*') > ) > > "Better" is going to depend on your initial reason for not wanting all > those function calls on one line. What is that reason? Well, I don't want those functions on a single line because having them multiline the code looks clearer. I asked here because I don't like the backslashes. Wrapping them in () looks like a good solution. -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On 9/17/19 2:59 PM, Manfred Lotz wrote: > def regex_from_filepat(fpat): > rfpat = fpat.replace('.', '\\.') \ >.replace('%', '.') \ >.replace('*', '.*') > > return '^' + rfpat + '$' > > As I don't want to have the replace() functions in one line my > question is if it is ok to spread the statement over various lines as > shown above, or if there is a better way? Is that way okay? Sure. Are there other ways? Sure. To isolate each replace() function on its own line, and to eliminate the clutter of the backslashes, consider this: rfpat = (fpat .replace('.', '\\.') .replace('%', '.') .replace('*', '.*') ) "Better" is going to depend on your initial reason for not wanting all those function calls on one line. What is that reason? -- https://mail.python.org/mailman/listinfo/python-list
Re: Spread a statement over various lines
On Tue, 17 Sep 2019 20:59:47 +0200 Manfred Lotz wrote: > I have a function like follows > > def regex_from_filepat(fpat): > rfpat = fpat.replace('.', '\\.') \ > .replace('%', '.') \ Not related to my question but the second replace must be: .replace('?', '.') -- https://mail.python.org/mailman/listinfo/python-list
Spread a statement over various lines
I have a function like follows def regex_from_filepat(fpat): rfpat = fpat.replace('.', '\\.') \ .replace('%', '.') \ .replace('*', '.*') return '^' + rfpat + '$' As I don't want to have the replace() functions in one line my question is if it is ok to spread the statement over various lines as shown above, or if there is a better way? Thanks. -- Manfred -- https://mail.python.org/mailman/listinfo/python-list