【问题标题】:How to properly escape within nested parentheses and brackets?如何在嵌套的括号和括号内正确转义?
【发布时间】:2015-05-29 14:49:51
【问题描述】:

我从没想过我会需要正则表达式方面的帮助,但它是这样的:

我正在寻找用于解析电子邮件地址的单个正则表达式:

  • someone@example.com{"name": "", "email": "someone@example.com"}
  • Some One <someone@example.com>{"name": "Some One", "email": "someone@example.com"}

正则表达式必须产生两个组:姓名和电子邮件。

这是我目前的状态:

regex = r"^((?P<name>[^(\s+\<)]*)\s+\<)?(?P<email>[^@]+?@[^>]+)>?$"

我绝对确定我需要在第一个嵌套块中转义某些内容,因为这是实际结果:

{'email': 'Some One <someone@example.com', 'name': None}

编辑:忘记在正则表达式中输入*(不回答问题)
EDIT2:solved。感谢大家的帮助。
EDIT3:重命名为:引用→转义

【问题讨论】:

  • @ConspicuousCompiler 这不是骗子;我很好 [^@]+@.+
  • 恐怕以我的看法,无论是哪种方式,这个问题都不太可能对未来的 SO 用户有所帮助。这个问题是在寻求正则表达式中的拼写错误的帮助,这不太可能帮助未来的搜索者,或者这个问题正在寻找权威的“如何正则表达式匹配电子邮件地址”,这在欺骗链接中得到了回答。跨度>
  • 我认为这对未来的读者很有帮助,因为它真的是关于嵌套括号和括号内的引用; see my answer
  • 几乎不可能将电子邮件地址与正则表达式匹配。见stackoverflow.com/q/201323/372239

标签: python regex email


【解决方案1】:

这里有几秒钟的答案(然后OP删除了它),里面有答案:

您需要双重转义

regex = r"^((?P<name>[^(\\s+\<)]*)\s+<)?(?P<email>[^@]+?@[^>]+)>?$"
                        ↑   ↑

编辑:引用→转义

EDIT2:
这个正则表达式效果更好:

r'^\s*(?P<name>[^\s<>](?:.*?[^\s<>])?)??\s*<?(?P<email>[^<>@\s]+@[^<>@\s]+)>?$'‌​

谢谢@tripleee

【讨论】:

  • 这指定了一个字符类,它匹配一个不打开圆括号的字符、文字反斜杠、字符s、字符+、字符&lt;(不必要地用反斜杠转义) 或右圆括号;该类可以匹配零次或多次(因此它实际上根本没有意义)。这一更改允许您解析单个测试用例这一事实是巧合。
  • @tripleee 这很有趣;在 python 中,正则表达式 [^()]* 匹配字符,直到括号中的子模式匹配(解释左括号)
  • 无论如何,这在Lastname First &lt;first.lastname@example.com&gt;&lt;address@example.com&gt; 上都失败了,没有真实姓名,但在电子邮件终端周围发生了故障。
  • First Middle Last &lt;fml@example.com&gt;Gregorius &lt;gorgeous@example.com&gt; 上也失败了。
  • 如果我能够理解您的尝试,我猜r'^\s*(?P&lt;name&gt;[^\s&lt;&gt;](?:.*?[^\s&lt;&gt;])?)??\s*&lt;?(?P&lt;email&gt;[^&lt;&gt;@\s]+@[^&lt;&gt;@\s]+)&gt;?$' 可能或多或少是您尝试完成的。在oldfashioned@example.net (Old Fashioned) 这样的地址上仍然会失败,但这些地址不再很受欢迎。
【解决方案2】:

“正则”表达式之所以被称为是因为它们指定了所谓的“常规语言”。这类语言的特点是上下文无关规则;例如,“bow”这个词只意味着一件事,不管它被哪个词包围(假设它是“what dogs say”的关键字)。这与上下文相关的语言不同,其中“我在你面前鞠躬”中的“鞠躬”与“用弓射击”不同,后者与“鞠躬哇”不同。

现代正则表达式在某种程度上超越了这个定义,但是,RFC822 中定义的From: 标头语法过于复杂,即使是增强的正则表达式引擎也无法解析。您确实需要一个上下文相关的语法(事实上,RFC5322 包括一个)来完全解析规范允许的每一个可能的变化。要连接到前面的示例,\" 的含义(即应该如何解析)取决于您是否在双引号内,以及您是否正在查看“真实姓名”、电子邮件终端或评论(在括号中)。

现在,您可能想退后一步,说只有一些可能的变体实际上是共同的、广泛使用的;确实如此,并且有正则表达式可以处理几乎所有这些。

http://code.iamcal.com/php/rfc822/tests/ 的测试套件上尝试您的正则表达式,然后自己决定哪些测试失败对您来说真正重要。也许您可以针对您“真正的意思”提出一个很好的规范。但是,就目前而言,您的问题必须用响亮的“无法完成”来回答。

【讨论】:

  • 我已经清楚地提供了输入和预期输出。我不是在寻找用于解析电子邮件地址的正则表达式。我已经有了这些。我只需要提取姓名和电子邮件。
  • 你没有道理。确定输入字符串的哪一部分是名称,哪一部分是电子邮件地址是解析的意思。如果你已经解决了这个问题,你为什么还要问?
  • 因为我还不能接受我自己的答案(我原来的帖子已经包含了解决方案的链接和“已解决”这个词)
  • 这仍然没有意义。您的问题是“我正在寻找一个用于解析电子邮件地址的正则表达式”,而现在您说您不是?
  • 为了您的娱乐,gist.github.com/tripleee/93d9c4c152e99fa4d976 包含一个简单的验证器脚本,它使用上面 URL 中的测试用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 2022-10-19
  • 2011-01-07
相关资源
最近更新 更多