评论正则表达式


11

是否有用于注释正则表达式的通用方法:内联注释引用RegEx的不同部分或针对所有表达式的常规注释?


2
有,但您需要更具体。例如,Bash支持内联注释,而Python提供了详细的正则表达式。
sakisk

6
我对正则表达式的经验法则是:如果您需要注释正则表达式,那就太复杂了。
zzzzBov 2012年

1
并始终包括以下链接:regexcrossword.com
Kieveli 2014年

我不一定同意,如果您必须对此进行评论,那就太复杂了。复杂的正则表达式仍可以为您节省大量令人眼花imp乱的命令性代码。使用良好的描述性变量名称将正则表达式分配给它。如果仍然不够清晰,请使用简短注释在正则表达式后传达原始意图
Craig

Answers:


10

我认为,一种好的做法是在注释中简明地说明正则表达式的一般概念。这样可以节省其他开发人员(有时是自己)的复制粘贴正则表达式像一个解析器的麻烦RegExr,不仅要了解它做什么。


2
RegExr仍然会发生,除非开发人员是正则表达式专家。但我同意提供一般描述;这就是我对正则表达式的处理方式。
罗伯特·哈维

3
+1:更详细的内容最终将成为正则表达式中的速成课程,作为注释。
马特

这个答案和@zzzzBov注释是有意义的。
m0nhawk

1
它不仅省去了对正则表达式进行繁琐检查的麻烦,而且使原始程序员的意图更加明确,特别是考虑到原始程序员很可能在第一时间弄错了正则表达式本身。话虽这么说,在许多情况下,将正则表达式分配给一个好的变量名可能对提供足够的意图文档很重要。
Craig

9

这在某种程度上是特定于语言的答案,但是问题中没有陈述任何语言。

“深入Python”一书建议使用Verbose正则表达式实现注释:

Python允许您使用称为详细正则表达式的方法来执行此操作。详细的正则表达式与紧凑的正则表达式在两个方面不同:

  • 空格被忽略。空格,制表符和回车符不匹配,因为空格,制表符和回车符。它们根本不匹配。(如果要在冗长的正则表达式中匹配空格,则需要在其前面加上反斜杠来对其进行转义。)
  • 评论将被忽略。冗长的正则表达式中的注释就像Python代码中的注释:它以#字符开头,一直到行尾。在这种情况下,它是多行字符串中的注释,而不是源代码中的注释,但是工作方式相同。

例:

>>> pattern = """
^                   # beginning of string
M{0,4}              # thousands - 0 to 4 M's
(CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                    #            or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                    #        or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                    #        or 5-8 (V, followed by 0 to 3 I's)
$                   # end of string
"""
>>> re.search(pattern, 'M', re.VERBOSE)                1

来源和进一步的细节在这里

此方法有一个轻微的缺点,即调用方必须知道该模式是以详细格式编写的,并相应地对其进行调用。


2
除了将模式存储在变量中之外,您还可以re.compile在定义模式时使用它,并且仅存储结果对象。这样,re.VERBOSE不需要将模式编译标志(包括)与模式本身分开。
约翰·巴塞洛缪

真的很有帮助,谢谢!但是,#如果我使用的是冗长标志,该如何匹配?顺便说一句:源链接似乎已关闭。
Winklerrr

好的,因此#可以在字符类中进行字面匹配:([#]来源:docs.python.org/3/library/re.html#re.X
winklerrr,

8

通常,我将编写一个正则表达式,而不是解释正则表达式的各个部分,而是解释其目的。那是什么,为什么。这有点像问“我的评论应该是什么样?” 有人会说“ 不要写代码在做什么,写代码为什么要做它所做的事情

// Strip the leading "?" and remove the query parameters "offset=<integer>" & "count=<integer> so we have a pattern of the request"          
var search = location.search.substring(1).replace(/offset=[0-9]+?&/g, "").replace(/count=[0-9]+?&/g, "");

除非您试图通过代码中的注释来教给别人有关正则表达式的知识,否则我不认为要解释每个部分的作用。与其他程序员一起工作时,您可以放心地假设一个人会知道一些全局正则表达式。


3
您会感到惊讶...
Matt

6

我想这真的取决于您如何将正则表达式放在一起。一般来说,我认为将注释放在实际的正则表达式字符串本身中是个坏主意(据我所知,在大多数情况下是不可能的)。如果确实需要注释正则表达式的特定部分(是否要教某人?),则将每个块分成单独的字符串,放在各自的行中,并使用编程语言的常规注释过程对每一行进行注释。否则,pleinolijf的答案就很好。

例:

string myregex = "\s" // Match any whitespace once
+ "\n"  // Match one newline character
+ "[a-zA-Z]";  // Match any letter

4

我通常定义一个字符串常量,其名称描述正则表达式的整体用途。

例如:

const string FloatingPointNumberPattern = @"[-+]?[0-9]*\.?[0-9]+";

您可以在此常量上方添加注释以对其进行描述,但通常常量名称本身就足够了。


1
我喜欢这个答案的另一件事是,如果将它用在多个地方,那么意图必须得到实现-别忘了对其进行评论。
J特拉纳2014年

3

在某些情况下,开发人员可能会使用正则表达式来匹配其典型域之外的文本。最初的开发人员可能经历了很多次迭代,捕获了可能仅通过该迭代过程发现的各种边缘情况。因此,即使后续开发人员知道一般情况,也可能不知道原始开发人员所处理的许多极端情况。

在这种情况下,可能值得记录这些变化的示例。本文档的位置可能因数量而异(例如,不一定在代码中)。

一种解决方法是,假设未来的开发人员将仅具有基本知识,例如正则表达式的工作原理,但不具备您(1)在开发正则表达式之前所未必知道的任何知识。未来的开发人员或(2)您在开发过程中获得的知识(例如,发现的边际案例)。

例如,如果在开发过程中您说类似“哦,我不知道X可以采用这种形式”,那么就值得记录一下(也许正则表达式中处理该变化的部分)。


2

注释应添加从代码中看不到的有用信息。

  1. 通过代码本身或注释,可以很容易地理解表达式在需求级别上应该做什么。表达式背后的目的是验证电子邮件地址或挑选加拿大电话号码。
  2. 易于理解表达式的实际作用,即表达式的计算结果。首先尝试通过拆分表达式来弄清楚,如果您先检查所有连字符,然后删除所有数字,然后使包含变量的变量的两部分表达式成为中间值,它将使阅读变得更加容易,阅读器将会能够一次一步地完成您的逻辑。(对于SE的一个问题,有一个著名的答案,即有人试图破译一些涉及位操作'>>'的旧代码,并找出是否设置了某些标志,答案不仅列出了代码的实际作用,还列出了如何做。问题的真实性应该在将来解构此类代码,这正是我要描述的内容,但是我可以

很少有应用程序需要每个最后一个周期,如果您要对海量数据集进行模式匹配,那么也许有更好的方法,也许没有,但是对于大多数情况而言,额外的执行时间并不重要。

并记住,下一个遇到您的代码并修复错误的人可能是六个月后的您,您将无法记住它应该做什么。


1

将RegEx提取到具有有意义名称的单独类中。然后,我用自动化测试记录了代码。

这将确保

  • 该代码实际上有效-也适用于特殊情况
  • 确保快速的“错误修正”不会破坏很多极端情况
  • 可能记录禁用回溯的优化

当然,您的课程可能会主持几个正则表达式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.