我如何编写 Python 正则表达式,它需要 4 个数字后跟拼音字母值?示例:1 2 3 4 阿尔法布拉沃 -> 1234AB
How can I write Python Regex that will take 4 numbers followed by Phonetic Alphabet values? Example: 1 2 3 4 Alpha Bravo -> 1234AB
我正在使用以下脚本,以便 Rasa 框架在用户传递荷兰邮政编码时检测到它:
https://medium.com/@naoko.reeves/rasa-regex-entity-extraction-317f047b28b6
荷兰邮政编码的格式是 1234 AB。这在使用像这样的正则表达式时效果很好:
[1-9][0-9]{3}[\s]?[a-z]{2}
但是,我现在正在尝试实现语音转文本功能(Azure 认知服务),该功能不太容易识别字母表。例如 'B' 被选为 'Bee'.
我现在正在尝试更改正则表达式,以便用户可以说“1 2 3 4 Alpha Bravo”,然后正则表达式提取器将挑选出“1 2 3 4 A B”。
我试过像下面这样使用单词边界:
[1-9]*[\s]?[0-9]*[\s]?[0-9]*[\s]?[0-9]*[\s]?\b[a-zA-Z]
和
[1-9]\s[0-9\s]{5}\s?\b[a-zA-Z]
前者过于宽松,如果用户说 'Hello There',它将触发正则表达式提取器并将 'HT' 传递给邮政编码行为。
后者更严格,但我只能将 '1 2 3 4 Alpha Bravo' 匹配为 '1 2 3 4 A'。
对于解决此问题的任何解决方案,我将不胜感激。如果这在 Regex 中不容易实现,我相信更改链接的中篇文章中的以下函数会得到我想要的结果。不幸的是,我不是 Python/Regex 专家 :)。
def match_regex(self, message):
extracted = []
for d in self.regex_feature:
match = re.search(pattern=d['pattern'], string=message)
if match:
entity = {
"start": match.pos,
"end": match.endpos,
"value": match.group(),
"confidence": 1.0,
"entity": d['name'],
}
extracted.append(entity)
extracted = self.add_extractor_name(extracted)
return extracted
我希望这已经够清楚了。
谢谢!
杰克
也许你可以试试这样的正则表达式:
(?i)\b([1-9][0-9]{3} ?[a-z])[a-z]* +([a-z])[a-z]*
无论此正则表达式匹配什么,只需将其替换为 </code> 即,第 1 组的内容后跟第 2 组的内容。</p>
<p><strong><a href="https://regex101.com/r/zYhc5W/1" rel="nofollow noreferrer">Click for Demo</a></strong></p>
<p><strong><a href="https://regex101.com/r/zYhc5W/1/codegen?language=python" rel="nofollow noreferrer">Click for Code</a></strong></p>
<p><strong>解释:</strong></p>
<ul>
<li><code>(?i)
- 切换使匹配不区分大小写
\b
- 单词边界
([1-9][0-9]{3} ?[a-z])
- 组 1 的内容如下所述
[1-9]
- 匹配从 1 到 9 的任何数字
[0-9]{3}
- 匹配从 0 到 9 的任意数字出现 3 次
?
- 匹配 0 次或 1 次出现的 space
[a-z]
- 匹配字母的单次出现。 这将是数字后第一个单词的第一个字母
[a-z]*
- 匹配出现 0 次以上的字母
+
- 匹配出现 1 次以上的 space
([a-z])
- 匹配一个字母并将其存储在 组 2 中。 这将是第二个单词的第一个字母
[a-z]*
- 匹配出现 0 次以上的字母
您可以使用 3 组匹配数字之间和大写字符 A-Z 之间的可选空格。
([1-9](?:\s*[0-9]){3})\s?([A-Z])[a-z]*\s*([A-Z])[a-z]*
模式匹配
([1-9](?:\s*[0-9]){3})
用可选的空白字符匹配 4 个数字
\s?
匹配一个可选的空格
([A-Z])[a-z]*\s*
匹配大写字符 A-Z,后跟可选的小写字符和可选的 whitespac
([A-Z])[a-z]*
匹配一个大写字符 A-Z,后跟可选的小写字符
更严格的选项可以匹配大写字符 A-Z,后跟相同字符的大写或小写变体,使用可选的重复反向引用
\b([1-9](?:\s*[0-9]){3})\s?([A-Z])(?i:*)\s*([A-Z])(?i:*)\b
import re
pattern = r"\b([1-9](?:\s*[0-9]){3})\s?([A-Z])(?i:*)\s*([A-Z])(?i:*)\b"
strings = [
"1 2 3 4 Alpha Bravo",
"1234 Alpha Bravo",
"1234A Bbbbbbbc",
"1234Aaa Bbb",
"1234Aa Bbb",
"1234A BbbbbBbb"
]
for s in strings:
print(re.findall(pattern, s))
输出
[]
[]
[]
[('1234', 'A', 'B')]
[('1234', 'A', 'B')]
[('1234', 'A', 'B')]
我正在使用以下脚本,以便 Rasa 框架在用户传递荷兰邮政编码时检测到它:
https://medium.com/@naoko.reeves/rasa-regex-entity-extraction-317f047b28b6
荷兰邮政编码的格式是 1234 AB。这在使用像这样的正则表达式时效果很好:
[1-9][0-9]{3}[\s]?[a-z]{2}
但是,我现在正在尝试实现语音转文本功能(Azure 认知服务),该功能不太容易识别字母表。例如 'B' 被选为 'Bee'.
我现在正在尝试更改正则表达式,以便用户可以说“1 2 3 4 Alpha Bravo”,然后正则表达式提取器将挑选出“1 2 3 4 A B”。
我试过像下面这样使用单词边界:
[1-9]*[\s]?[0-9]*[\s]?[0-9]*[\s]?[0-9]*[\s]?\b[a-zA-Z]
和
[1-9]\s[0-9\s]{5}\s?\b[a-zA-Z]
前者过于宽松,如果用户说 'Hello There',它将触发正则表达式提取器并将 'HT' 传递给邮政编码行为。
后者更严格,但我只能将 '1 2 3 4 Alpha Bravo' 匹配为 '1 2 3 4 A'。
对于解决此问题的任何解决方案,我将不胜感激。如果这在 Regex 中不容易实现,我相信更改链接的中篇文章中的以下函数会得到我想要的结果。不幸的是,我不是 Python/Regex 专家 :)。
def match_regex(self, message):
extracted = []
for d in self.regex_feature:
match = re.search(pattern=d['pattern'], string=message)
if match:
entity = {
"start": match.pos,
"end": match.endpos,
"value": match.group(),
"confidence": 1.0,
"entity": d['name'],
}
extracted.append(entity)
extracted = self.add_extractor_name(extracted)
return extracted
我希望这已经够清楚了。
谢谢!
杰克
也许你可以试试这样的正则表达式:
(?i)\b([1-9][0-9]{3} ?[a-z])[a-z]* +([a-z])[a-z]*
无论此正则表达式匹配什么,只需将其替换为 </code> 即,第 1 组的内容后跟第 2 组的内容。</p>
<p><strong><a href="https://regex101.com/r/zYhc5W/1" rel="nofollow noreferrer">Click for Demo</a></strong></p>
<p><strong><a href="https://regex101.com/r/zYhc5W/1/codegen?language=python" rel="nofollow noreferrer">Click for Code</a></strong></p>
<p><strong>解释:</strong></p>
<ul>
<li><code>(?i)
- 切换使匹配不区分大小写
\b
- 单词边界([1-9][0-9]{3} ?[a-z])
- 组 1 的内容如下所述
[1-9]
- 匹配从 1 到 9 的任何数字[0-9]{3}
- 匹配从 0 到 9 的任意数字出现 3 次?
- 匹配 0 次或 1 次出现的 space[a-z]
- 匹配字母的单次出现。 这将是数字后第一个单词的第一个字母
[a-z]*
- 匹配出现 0 次以上的字母 +
- 匹配出现 1 次以上的 space([a-z])
- 匹配一个字母并将其存储在 组 2 中。 这将是第二个单词的第一个字母[a-z]*
- 匹配出现 0 次以上的字母您可以使用 3 组匹配数字之间和大写字符 A-Z 之间的可选空格。
([1-9](?:\s*[0-9]){3})\s?([A-Z])[a-z]*\s*([A-Z])[a-z]*
模式匹配
([1-9](?:\s*[0-9]){3})
用可选的空白字符匹配 4 个数字\s?
匹配一个可选的空格([A-Z])[a-z]*\s*
匹配大写字符 A-Z,后跟可选的小写字符和可选的 whitespac([A-Z])[a-z]*
匹配一个大写字符 A-Z,后跟可选的小写字符
更严格的选项可以匹配大写字符 A-Z,后跟相同字符的大写或小写变体,使用可选的重复反向引用
\b([1-9](?:\s*[0-9]){3})\s?([A-Z])(?i:*)\s*([A-Z])(?i:*)\b
import re
pattern = r"\b([1-9](?:\s*[0-9]){3})\s?([A-Z])(?i:*)\s*([A-Z])(?i:*)\b"
strings = [
"1 2 3 4 Alpha Bravo",
"1234 Alpha Bravo",
"1234A Bbbbbbbc",
"1234Aaa Bbb",
"1234Aa Bbb",
"1234A BbbbbBbb"
]
for s in strings:
print(re.findall(pattern, s))
输出
[]
[]
[]
[('1234', 'A', 'B')]
[('1234', 'A', 'B')]
[('1234', 'A', 'B')]