复数的正则表达式
Regular expression for complex numbers
所以我正在尝试为复数编写正则表达式(就像学习 re 模块的练习)。但我无法让它工作。我希望正则表达式匹配以下形式的字符串:'12+18j'、'-14+45j'、'54'、'-87j' 等等。我的尝试:
import re
num = r'[+-]?(?:\d*.\d+|\d+)'
complex_pattern = rf'(?:(?P<real>{num})|(?P<imag>{num}j))|(?:(?P=real)(?P=imag))'
complex_pattern = re.compile(complex_pattern)
但它并没有真正如我所愿。
m = complex_pattern.fullmatch('1+12j')
m.groupdict()
Out[166]: {'real': None, 'imag': '1+12j'}
其结构背后的原因是我希望输入字符串包含实部或虚部或两者。并且还能够从匹配对象中提取真实和图像组。我尝试了其他方法,它似乎有效,除了它捕获空字符串 (''):
complex_pattern = rf'(?P<real>{num})+(?P<imag>{num}j)+'
complex_pattern = re.compile(complex_pattern)
我想我可以简单地使用 if 来检查空字符串。但我对更纯粹的方式感兴趣,并且想知道为什么第一次实施没有按预期工作。
这对你想要的有用吗?
import re
words= '+122+6766j'
pattern = re.compile(r'((^[-+]?(?P<real>\d+))?[-+]?(?P<img>\d{2,}j?\w)?)')
pattern.fullmatch(words).groupdict()
输出
{'real': '122', 'img': '6766j'}
我建议使用
import re
pattern = r'^(?!$)(?P<real>(?P<sign1>[+-]?)(?P<number1>\d+(?:\.\d+)?))?(?:(?P<imag>(?P<sign2>[+-]?)(?P<number2>\d+(?:\.\d+)?j)))?$'
texts = ['1+12j', '12+18j','-14+45j','54','-87j']
for text in texts:
match = re.fullmatch(pattern, text)
if match:
print(text, '=>', match.groupdict())
else:
print(f'{text} did not match!')
见Python demo。输出:
1+12j => {'real': '1', 'sign1': '', 'number1': '1', 'imag': '+12j', 'sign2': '+', 'number2': '12j'}
12+18j => {'real': '12', 'sign1': '', 'number1': '12', 'imag': '+18j', 'sign2': '+', 'number2': '18j'}
-14+45j => {'real': '-14', 'sign1': '-', 'number1': '14', 'imag': '+45j', 'sign2': '+', 'number2': '45j'}
54 => {'real': '54', 'sign1': '', 'number1': '54', 'imag': None, 'sign2': None, 'number2': None}
-87j => {'real': '-8', 'sign1': '-', 'number1': '8', 'imag': '7j', 'sign2': '', 'number2': '7j'}
参见regex demo。
详情
^
- 字符串开头
(?!$)
- 此位置不应有字符串结尾(不允许空输入)
(?P<real>(?P<sign1>[+-]?)(?P<number1>\d+(?:\.\d+)?))?
- “真实”组:
(?P<sign1>[+-]?)
- 一个可选的 -
或 +
符号捕获到组“sign1”
(?P<number1>\d+(?:\.\d+)?)
- 一个或多个数字后跟可选的 .
序列和一个或多个数字捕获到组“number1”
(?P<imag>(?P<sign2>[+-]?)(?P<number2>\d+(?:\.\d+)?j))?
- 捕获到“imag”组中的可选序列:
(?P<sign2>[+-]?)
- 一个可选的 -
或 +
符号捕获到组“sign2”
(?P<number2>\d+(?:\.\d+)?j)
- 一位或多位数字后跟一个可选序列 .
和一位或多位数字,然后是 j
字符捕获到组“number2”[=52] =]
$
- 字符串结尾。
尽管我接受了 回答并认为它非常好。我必须添加一些我注意到的东西。首先,texts
列表中的最后一个字符串没有正确分组(即 '-87j' -> real: -8; imag: 7j)。为了解决这个问题,我建议对他的答案的简化版本进行以下更改:
import re
num = r'[+-]?(?:\d*\.\d+|\d+)'
pattern = rf'(?!$)(?P<real>{num}(?!\d))?(?P<imag>{num}j)?'
texts = ['1+12j', '12+18j','-14+45j','54','-87j']
for text in texts:
match = re.fullmatch(pattern, text)
if match:
print(f'{text:>7} => {match.groupdict()}')
else:
print(f'{text:>7} did not match!')
输出:
1+12j => {'real': '1', 'imag': '+12j'}
12+18j => {'real': '12', 'imag': '+18j'}
-14+45j => {'real': '-14', 'imag': '+45j'}
54 => {'real': '54', 'imag': None}
-87j => {'real': None, 'imag': '-87j'}
这里的重要区别是将 (?!\d)
添加到 'real' 组正则表达式中,以防止像 '-87j' 这样的字符串被拆分为 '-8' 和 '7j'。
所以我正在尝试为复数编写正则表达式(就像学习 re 模块的练习)。但我无法让它工作。我希望正则表达式匹配以下形式的字符串:'12+18j'、'-14+45j'、'54'、'-87j' 等等。我的尝试:
import re
num = r'[+-]?(?:\d*.\d+|\d+)'
complex_pattern = rf'(?:(?P<real>{num})|(?P<imag>{num}j))|(?:(?P=real)(?P=imag))'
complex_pattern = re.compile(complex_pattern)
但它并没有真正如我所愿。
m = complex_pattern.fullmatch('1+12j')
m.groupdict()
Out[166]: {'real': None, 'imag': '1+12j'}
其结构背后的原因是我希望输入字符串包含实部或虚部或两者。并且还能够从匹配对象中提取真实和图像组。我尝试了其他方法,它似乎有效,除了它捕获空字符串 (''):
complex_pattern = rf'(?P<real>{num})+(?P<imag>{num}j)+'
complex_pattern = re.compile(complex_pattern)
我想我可以简单地使用 if 来检查空字符串。但我对更纯粹的方式感兴趣,并且想知道为什么第一次实施没有按预期工作。
这对你想要的有用吗?
import re
words= '+122+6766j'
pattern = re.compile(r'((^[-+]?(?P<real>\d+))?[-+]?(?P<img>\d{2,}j?\w)?)')
pattern.fullmatch(words).groupdict()
输出
{'real': '122', 'img': '6766j'}
我建议使用
import re
pattern = r'^(?!$)(?P<real>(?P<sign1>[+-]?)(?P<number1>\d+(?:\.\d+)?))?(?:(?P<imag>(?P<sign2>[+-]?)(?P<number2>\d+(?:\.\d+)?j)))?$'
texts = ['1+12j', '12+18j','-14+45j','54','-87j']
for text in texts:
match = re.fullmatch(pattern, text)
if match:
print(text, '=>', match.groupdict())
else:
print(f'{text} did not match!')
见Python demo。输出:
1+12j => {'real': '1', 'sign1': '', 'number1': '1', 'imag': '+12j', 'sign2': '+', 'number2': '12j'}
12+18j => {'real': '12', 'sign1': '', 'number1': '12', 'imag': '+18j', 'sign2': '+', 'number2': '18j'}
-14+45j => {'real': '-14', 'sign1': '-', 'number1': '14', 'imag': '+45j', 'sign2': '+', 'number2': '45j'}
54 => {'real': '54', 'sign1': '', 'number1': '54', 'imag': None, 'sign2': None, 'number2': None}
-87j => {'real': '-8', 'sign1': '-', 'number1': '8', 'imag': '7j', 'sign2': '', 'number2': '7j'}
参见regex demo。
详情
^
- 字符串开头(?!$)
- 此位置不应有字符串结尾(不允许空输入)(?P<real>(?P<sign1>[+-]?)(?P<number1>\d+(?:\.\d+)?))?
- “真实”组:(?P<sign1>[+-]?)
- 一个可选的-
或+
符号捕获到组“sign1”(?P<number1>\d+(?:\.\d+)?)
- 一个或多个数字后跟可选的.
序列和一个或多个数字捕获到组“number1”
(?P<imag>(?P<sign2>[+-]?)(?P<number2>\d+(?:\.\d+)?j))?
- 捕获到“imag”组中的可选序列:(?P<sign2>[+-]?)
- 一个可选的-
或+
符号捕获到组“sign2”(?P<number2>\d+(?:\.\d+)?j)
- 一位或多位数字后跟一个可选序列.
和一位或多位数字,然后是j
字符捕获到组“number2”[=52] =]
$
- 字符串结尾。
尽管我接受了 texts
列表中的最后一个字符串没有正确分组(即 '-87j' -> real: -8; imag: 7j)。为了解决这个问题,我建议对他的答案的简化版本进行以下更改:
import re
num = r'[+-]?(?:\d*\.\d+|\d+)'
pattern = rf'(?!$)(?P<real>{num}(?!\d))?(?P<imag>{num}j)?'
texts = ['1+12j', '12+18j','-14+45j','54','-87j']
for text in texts:
match = re.fullmatch(pattern, text)
if match:
print(f'{text:>7} => {match.groupdict()}')
else:
print(f'{text:>7} did not match!')
输出:
1+12j => {'real': '1', 'imag': '+12j'}
12+18j => {'real': '12', 'imag': '+18j'}
-14+45j => {'real': '-14', 'imag': '+45j'}
54 => {'real': '54', 'imag': None}
-87j => {'real': None, 'imag': '-87j'}
这里的重要区别是将 (?!\d)
添加到 'real' 组正则表达式中,以防止像 '-87j' 这样的字符串被拆分为 '-8' 和 '7j'。