Regex - word-boundary
Verfasst: Donnerstag 26. August 2021, 15:47
Liebes Forum,
ich will von einem String herausfinden, ob er die Zeichenfolge 'id' entweder alleine oder abgetrennt, aber nicht als Bestandteil eines Wortes enthält. Also
'id' soll matchen, desgleichen z.B. 'customer_id', nicht aber 'middle'.
Zunächst habe ich es mit '\bid\b' versucht, das hat nicht funktioniert (siehe Codebeispiel unten und die dazugehörige Ausgabe).
Dann habe ich mir eine word-boundary selbst gebaut: '(.*[^a-zA-Z])?id([^a-zA-Z].*)?'
Das interessante Phänomen dabei: verwende ich re.fullmatch funktioniert es für alle (von mir betrachteten) Fälle, verwende ich nur re.match wird z.B. 'identity' fälschlicherweise (nun ja, also nach meinem Begriff, aber möglicherweise sitze ich da einem Denkfehler auf, vielleicht kann mir da jemand helfen) als match gefunden...
Der Code sieht bei mir folgendermaßen aus:
--------------------------------------------------------------------------
import re
import pytest
test_string_01 = 'id'
test_string_02 = 'mid'
test_string_03 = 'middle'
test_string_04 = 'identity'
test_string_05_b = 'customer id'
test_string_05 = 'customer_id'
test_string_06_b = 'id validation'
test_string_06 = 'id_validation'
test_string_07 = 'some_id_included'
test_string_07_b = 'some id included'
test_string_08 = 'in_the_middle_id_more'
test_string_08_b = 'in the middle id more'
match_pattern = '\bid\b'
print("matching test_string_01 '" + test_string_01 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_01)))
print("matching test_string_02 '" + test_string_02 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_02)))
print("matching test_string_03 '" + test_string_03 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_03)))
print("matching test_string_04 '" + test_string_04 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_04)))
print("matching test_string_05 '" + test_string_05 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05)))
print("matching test_string_05_b '" + test_string_05_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05_b)))
print("matching test_string_06 '" + test_string_06 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06)))
print("matching test_string_06_b '" + test_string_06_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06_b)))
print("matching test_string_07 '" + test_string_07 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07)))
print("matching test_string_07_b '" + test_string_07_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07_b)))
print("matching test_string_08 '" + test_string_08 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08)))
print("matching test_string_08_b '" + test_string_08_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08_b)))
match_pattern = '(.*[^a-zA-Z])?id([^a-zA-Z].*)?'
print("matching test_string_01 '" + test_string_01 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_01)))
print("matching test_string_02 '" + test_string_02 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_02)))
print("matching test_string_03 '" + test_string_03 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_03)))
print("matching test_string_04 '" + test_string_04 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_04)))
print("matching test_string_05 '" + test_string_05 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05)))
print("matching test_string_05_b '" + test_string_05_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05_b)))
print("matching test_string_06 '" + test_string_06 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06)))
print("matching test_string_06_b '" + test_string_06_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06_b)))
print("matching test_string_07 '" + test_string_07 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07)))
print("matching test_string_07_b '" + test_string_07_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07_b)))
print("matching test_string_08 '" + test_string_08 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08)))
print("matching test_string_08_b '" + test_string_08_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08_b)))
print("\n ### +++ Now the same thing with 'fullmatch'... +++ ###\n")
print("matching test_string_01 '" + test_string_01 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_01)))
print("matching test_string_02 '" + test_string_02 + "' (exp.: No Match) " + str(re.fullmatch(match_pattern, test_string_02)))
print("matching test_string_03 '" + test_string_03 + "' (exp.: No Match) " + str(re.fullmatch(match_pattern, test_string_03)))
print("matching test_string_04 '" + test_string_04 + "' (exp.: No Match) " + str(re.fullmatch(match_pattern, test_string_04)))
print("matching test_string_05 '" + test_string_05 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_05)))
print("matching test_string_05_b '" + test_string_05_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_05_b)))
print("matching test_string_06 '" + test_string_06 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_06)))
print("matching test_string_06_b '" + test_string_06_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_06_b)))
print("matching test_string_07 '" + test_string_07 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_07)))
print("matching test_string_07_b '" + test_string_07_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_07_b)))
print("matching test_string_08 '" + test_string_08 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_08)))
print("matching test_string_08_b '" + test_string_08_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_08_b)))
--------------------------------------------------------------------------
und die Ausgabe folgendermaßen:
======================================
matching test_string_01 'id' (exp.: Match) None
matching test_string_02 'mid' (exp.: No Match) None
matching test_string_03 'middle' (exp.: No Match) None
matching test_string_04 'identity' (exp.: No Match) None
matching test_string_05 'customer_id' (exp.: Match) None
matching test_string_05_b 'customer id' (exp.: Match) None
matching test_string_06 'id_validation' (exp.: Match) None
matching test_string_06_b 'id validation' (exp.: Match) None
matching test_string_07 'some_id_included' (exp.: Match) None
matching test_string_07_b 'some id included' (exp.: Match) None
matching test_string_08 'in_the_middle_id_more' (exp.: Match) None
matching test_string_08_b 'in the middle id more' (exp.: Match) None
matching test_string_01 'id' (exp.: Match) <re.Match object; span=(0, 2), match='id'>
matching test_string_02 'mid' (exp.: No Match) None
matching test_string_03 'middle' (exp.: No Match) None
matching test_string_04 'identity' (exp.: No Match) <re.Match object; span=(0, 2), match='id'>
matching test_string_05 'customer_id' (exp.: Match) <re.Match object; span=(0, 11), match='customer_id'>
matching test_string_05_b 'customer id' (exp.: Match) <re.Match object; span=(0, 11), match='customer id'>
matching test_string_06 'id_validation' (exp.: Match) <re.Match object; span=(0, 13), match='id_validation'>
matching test_string_06_b 'id validation' (exp.: Match) <re.Match object; span=(0, 13), match='id validation'>
matching test_string_07 'some_id_included' (exp.: Match) <re.Match object; span=(0, 16), match='some_id_included'>
matching test_string_07_b 'some id included' (exp.: Match) <re.Match object; span=(0, 16), match='some id included'>
matching test_string_08 'in_the_middle_id_more' (exp.: Match) <re.Match object; span=(0, 21), match='in_the_middle_id_more'>
matching test_string_08_b 'in the middle id more' (exp.: Match) <re.Match object; span=(0, 21), match='in the middle id more'>
### +++ Now the same thing with 'fullmatch'... +++ ###
matching test_string_01 'id' (exp.: Match) <re.Match object; span=(0, 2), match='id'>
matching test_string_02 'mid' (exp.: No Match) None
matching test_string_03 'middle' (exp.: No Match) None
matching test_string_04 'identity' (exp.: No Match) None
matching test_string_05 'customer_id' (exp.: Match) <re.Match object; span=(0, 11), match='customer_id'>
matching test_string_05_b 'customer id' (exp.: Match) <re.Match object; span=(0, 11), match='customer id'>
matching test_string_06 'id_validation' (exp.: Match) <re.Match object; span=(0, 13), match='id_validation'>
matching test_string_06_b 'id validation' (exp.: Match) <re.Match object; span=(0, 13), match='id validation'>
matching test_string_07 'some_id_included' (exp.: Match) <re.Match object; span=(0, 16), match='some_id_included'>
matching test_string_07_b 'some id included' (exp.: Match) <re.Match object; span=(0, 16), match='some id included'>
matching test_string_08 'in_the_middle_id_more' (exp.: Match) <re.Match object; span=(0, 21), match='in_the_middle_id_more'>
matching test_string_08_b 'in the middle id more' (exp.: Match) <re.Match object; span=(0, 21), match='in the middle id more'>
======================================
(btw.: gibt es eine in der community übliche Möglichkeit, Code-snippets bzw. Ausgabe-Snippets deutlich vom umgebenden Text abzugrenzen? ich habe hier halt einmal --- und === verwendet, aber vielleicht gibt es etwas besseres...)
Noch einmal zusammenfassend:
(1) Wieso funktioniert es mit \b nicht und ich erhalte überhaupt keine matches?
(2) Beim angegebenen match_pattern hätte ich erwartet, dass sich re.match und re.fullmatch gleich verhalten (ich biete ja ein Pattern an, das im Prinzip den ganzen String abdecken könnte). Und nicht, dass re.match irgendetwas _nicht_ matchen würde, was re.fullmatch matcht (das könnte ich ja noch eher verstehen), sondern genau umgekehrt. Was habe ich da nicht verstanden?
Bin für jeden Hinweis dankbar.
cuddle Panda
ich will von einem String herausfinden, ob er die Zeichenfolge 'id' entweder alleine oder abgetrennt, aber nicht als Bestandteil eines Wortes enthält. Also
'id' soll matchen, desgleichen z.B. 'customer_id', nicht aber 'middle'.
Zunächst habe ich es mit '\bid\b' versucht, das hat nicht funktioniert (siehe Codebeispiel unten und die dazugehörige Ausgabe).
Dann habe ich mir eine word-boundary selbst gebaut: '(.*[^a-zA-Z])?id([^a-zA-Z].*)?'
Das interessante Phänomen dabei: verwende ich re.fullmatch funktioniert es für alle (von mir betrachteten) Fälle, verwende ich nur re.match wird z.B. 'identity' fälschlicherweise (nun ja, also nach meinem Begriff, aber möglicherweise sitze ich da einem Denkfehler auf, vielleicht kann mir da jemand helfen) als match gefunden...
Der Code sieht bei mir folgendermaßen aus:
--------------------------------------------------------------------------
import re
import pytest
test_string_01 = 'id'
test_string_02 = 'mid'
test_string_03 = 'middle'
test_string_04 = 'identity'
test_string_05_b = 'customer id'
test_string_05 = 'customer_id'
test_string_06_b = 'id validation'
test_string_06 = 'id_validation'
test_string_07 = 'some_id_included'
test_string_07_b = 'some id included'
test_string_08 = 'in_the_middle_id_more'
test_string_08_b = 'in the middle id more'
match_pattern = '\bid\b'
print("matching test_string_01 '" + test_string_01 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_01)))
print("matching test_string_02 '" + test_string_02 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_02)))
print("matching test_string_03 '" + test_string_03 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_03)))
print("matching test_string_04 '" + test_string_04 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_04)))
print("matching test_string_05 '" + test_string_05 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05)))
print("matching test_string_05_b '" + test_string_05_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05_b)))
print("matching test_string_06 '" + test_string_06 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06)))
print("matching test_string_06_b '" + test_string_06_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06_b)))
print("matching test_string_07 '" + test_string_07 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07)))
print("matching test_string_07_b '" + test_string_07_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07_b)))
print("matching test_string_08 '" + test_string_08 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08)))
print("matching test_string_08_b '" + test_string_08_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08_b)))
match_pattern = '(.*[^a-zA-Z])?id([^a-zA-Z].*)?'
print("matching test_string_01 '" + test_string_01 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_01)))
print("matching test_string_02 '" + test_string_02 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_02)))
print("matching test_string_03 '" + test_string_03 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_03)))
print("matching test_string_04 '" + test_string_04 + "' (exp.: No Match) " + str(re.match(match_pattern, test_string_04)))
print("matching test_string_05 '" + test_string_05 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05)))
print("matching test_string_05_b '" + test_string_05_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_05_b)))
print("matching test_string_06 '" + test_string_06 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06)))
print("matching test_string_06_b '" + test_string_06_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_06_b)))
print("matching test_string_07 '" + test_string_07 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07)))
print("matching test_string_07_b '" + test_string_07_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_07_b)))
print("matching test_string_08 '" + test_string_08 + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08)))
print("matching test_string_08_b '" + test_string_08_b + "' (exp.: Match) " + str(re.match(match_pattern, test_string_08_b)))
print("\n ### +++ Now the same thing with 'fullmatch'... +++ ###\n")
print("matching test_string_01 '" + test_string_01 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_01)))
print("matching test_string_02 '" + test_string_02 + "' (exp.: No Match) " + str(re.fullmatch(match_pattern, test_string_02)))
print("matching test_string_03 '" + test_string_03 + "' (exp.: No Match) " + str(re.fullmatch(match_pattern, test_string_03)))
print("matching test_string_04 '" + test_string_04 + "' (exp.: No Match) " + str(re.fullmatch(match_pattern, test_string_04)))
print("matching test_string_05 '" + test_string_05 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_05)))
print("matching test_string_05_b '" + test_string_05_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_05_b)))
print("matching test_string_06 '" + test_string_06 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_06)))
print("matching test_string_06_b '" + test_string_06_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_06_b)))
print("matching test_string_07 '" + test_string_07 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_07)))
print("matching test_string_07_b '" + test_string_07_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_07_b)))
print("matching test_string_08 '" + test_string_08 + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_08)))
print("matching test_string_08_b '" + test_string_08_b + "' (exp.: Match) " + str(re.fullmatch(match_pattern, test_string_08_b)))
--------------------------------------------------------------------------
und die Ausgabe folgendermaßen:
======================================
matching test_string_01 'id' (exp.: Match) None
matching test_string_02 'mid' (exp.: No Match) None
matching test_string_03 'middle' (exp.: No Match) None
matching test_string_04 'identity' (exp.: No Match) None
matching test_string_05 'customer_id' (exp.: Match) None
matching test_string_05_b 'customer id' (exp.: Match) None
matching test_string_06 'id_validation' (exp.: Match) None
matching test_string_06_b 'id validation' (exp.: Match) None
matching test_string_07 'some_id_included' (exp.: Match) None
matching test_string_07_b 'some id included' (exp.: Match) None
matching test_string_08 'in_the_middle_id_more' (exp.: Match) None
matching test_string_08_b 'in the middle id more' (exp.: Match) None
matching test_string_01 'id' (exp.: Match) <re.Match object; span=(0, 2), match='id'>
matching test_string_02 'mid' (exp.: No Match) None
matching test_string_03 'middle' (exp.: No Match) None
matching test_string_04 'identity' (exp.: No Match) <re.Match object; span=(0, 2), match='id'>
matching test_string_05 'customer_id' (exp.: Match) <re.Match object; span=(0, 11), match='customer_id'>
matching test_string_05_b 'customer id' (exp.: Match) <re.Match object; span=(0, 11), match='customer id'>
matching test_string_06 'id_validation' (exp.: Match) <re.Match object; span=(0, 13), match='id_validation'>
matching test_string_06_b 'id validation' (exp.: Match) <re.Match object; span=(0, 13), match='id validation'>
matching test_string_07 'some_id_included' (exp.: Match) <re.Match object; span=(0, 16), match='some_id_included'>
matching test_string_07_b 'some id included' (exp.: Match) <re.Match object; span=(0, 16), match='some id included'>
matching test_string_08 'in_the_middle_id_more' (exp.: Match) <re.Match object; span=(0, 21), match='in_the_middle_id_more'>
matching test_string_08_b 'in the middle id more' (exp.: Match) <re.Match object; span=(0, 21), match='in the middle id more'>
### +++ Now the same thing with 'fullmatch'... +++ ###
matching test_string_01 'id' (exp.: Match) <re.Match object; span=(0, 2), match='id'>
matching test_string_02 'mid' (exp.: No Match) None
matching test_string_03 'middle' (exp.: No Match) None
matching test_string_04 'identity' (exp.: No Match) None
matching test_string_05 'customer_id' (exp.: Match) <re.Match object; span=(0, 11), match='customer_id'>
matching test_string_05_b 'customer id' (exp.: Match) <re.Match object; span=(0, 11), match='customer id'>
matching test_string_06 'id_validation' (exp.: Match) <re.Match object; span=(0, 13), match='id_validation'>
matching test_string_06_b 'id validation' (exp.: Match) <re.Match object; span=(0, 13), match='id validation'>
matching test_string_07 'some_id_included' (exp.: Match) <re.Match object; span=(0, 16), match='some_id_included'>
matching test_string_07_b 'some id included' (exp.: Match) <re.Match object; span=(0, 16), match='some id included'>
matching test_string_08 'in_the_middle_id_more' (exp.: Match) <re.Match object; span=(0, 21), match='in_the_middle_id_more'>
matching test_string_08_b 'in the middle id more' (exp.: Match) <re.Match object; span=(0, 21), match='in the middle id more'>
======================================
(btw.: gibt es eine in der community übliche Möglichkeit, Code-snippets bzw. Ausgabe-Snippets deutlich vom umgebenden Text abzugrenzen? ich habe hier halt einmal --- und === verwendet, aber vielleicht gibt es etwas besseres...)
Noch einmal zusammenfassend:
(1) Wieso funktioniert es mit \b nicht und ich erhalte überhaupt keine matches?
(2) Beim angegebenen match_pattern hätte ich erwartet, dass sich re.match und re.fullmatch gleich verhalten (ich biete ja ein Pattern an, das im Prinzip den ganzen String abdecken könnte). Und nicht, dass re.match irgendetwas _nicht_ matchen würde, was re.fullmatch matcht (das könnte ich ja noch eher verstehen), sondern genau umgekehrt. Was habe ich da nicht verstanden?
Bin für jeden Hinweis dankbar.
cuddle Panda