正则表达式匹配单个字符实例

Kir*_*irk 9 awk text-processing regular-expression

我在工作中维护了这个东西,它使用了一个相当神秘的 DSL。而且它的工具不是很好。为了解决糟糕的工具问题,我编写了一些脚本,试图在将代码发送到生产环境之前找到代码的一些问题。

我当前试图解决的问题与变量名有关。变量的命名类似于@@Variable@@. 如果只有 1 秒@或超过 2@秒,则为致命错误。

现在我已经让它循环遍历有问题的文件,并@@@在发现 3 个或更多连续的 时进行 grep 并引发错误@。所以那部分很酷。

但我有点陷入单身状态@。一行上可以有多个变量。

@@Var1@@ words words words @@Var2@@  #This works
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.
Run Code Online (Sandbox Code Playgroud)

上面有很多排列,并且一行上的变量数量没有限制。

如果任何给定行上只有一个变量,则此 awk 脚本可以工作,但如果一行上有多个变量,则该 awk 脚本将不起作用。

awk '/@/ && ! /@@.*@@/' test.txt
Run Code Online (Sandbox Code Playgroud)

我真正需要做的是匹配只有一个@. 在上面的示例代码中,它将匹配除第 1 行之外的所有行。

Kus*_*nda 7

$ sed 'h;s/@@[^@ ]*@@//g;/@/!d;g' file
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.
Run Code Online (Sandbox Code Playgroud)

sed命令删除有效的变量占位符并报告仍包含@字符的行。它还会找到包含@两侧都有两个以上占位符的行。

我们可以通过将每行保存到保留空间来报告原始的故障行h。然后运行删除潜在有效占位符的替换,如果之后不包含任何@字符,我们将删除该行。我们从保留空间中获取原始行,g如果存在则打印它。

如果您的变量遵循与大多数编程语言相同的命名规则,则可以将有效占位符 的模式@@[^@ ]*@@更改为。@@[[:alpha:]_][[:alnum:]_]*@@

假设您需要能够@在文本本身中包含字符。在这种情况下,您需要在上面命令中的替换之前删除所有@可能出现的不是变量占位符的有效星座。


一种更系统的方法是提取包含占位符的行,@其中一侧或另一侧有太多字符,删除正确的占位符,然后拉出占位符@在变量名称的两侧仅包含一个字符的行。

sed -e '/@\{3,\}[^@ ]*@\{1,\}/b' \
    -e '/@\{1,\}[^@ ]*@\{3,\}/b' \
    -e h \
    -e 's/@@[^@ ]*@@//g' \
    -e '/@[^@ ]*@/!d' \
    -e g file
Run Code Online (Sandbox Code Playgroud)

上面的内容将允许您的文本在其他地方包含@字符,前提是它们不会以看起来像占位符的模式出现。


Ed *_*ton 6

$ grep -E '(^|[^@])@([^@]|$)|@@@' file
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.
Run Code Online (Sandbox Code Playgroud)

或者:

$ awk '/(^|[^@])@([^@]|$)|@@@/' file
@Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
@@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
@@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.
Run Code Online (Sandbox Code Playgroud)

或一次分析一个字段:

$ cat tst.awk
{
    for (i=1; i<=NF; i++) {
        if ( $i ~ /^@[^@]|[^@]@$|@@@/ ) {
            print "Failed line:", NR, $0
            print "\tbecause of field", i, $i
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

$ awk -f tst.awk file
Failed line: 2 @Var1@@ words words words @@Var2@@   #This will fail because Var1 is wrong.
        because of field 1 @Var1@@
Failed line: 3 @@Var1@ words words words @@Var2@@   #This will fail because Var1 is wrong.
        because of field 1 @@Var1@
Failed line: 4 @@Var1@@ words words words @Var2@@   #This will fail because Var2 is wrong.
        because of field 5 @Var2@@
Failed line: 5 @@Var1@@ words words words @@Var2@   #This will fail because Var2 is wrong.
        because of field 5 @@Var2@
Run Code Online (Sandbox Code Playgroud)

您不需要任何额外的东西来查找@@@案例,上面也包括查找该案例。