正则表达式匹配不带双_的标识符

正则表达式匹配不带双_的标识符

我想要一个正则表达式来匹配由字母、数字和组成的标识符_,不带双下划线。我目前的尝试:

^(?!_)(?!.*?_$)[a-zA-Z][a-zA-Z0-9_]+$

例子:

Abdfsdfsdf__ 
1B2345_
v1__23456
__23456789b
12345-6789
123456789
1_fsdfdfsdf
v_fsdfsdf_fsdfd
v_123
v__123
v134234_fsdfsd
123456
a1b2c3d4e5

匹配:

v1__23456
v_fsdfsdf_fsdfd
v_123
v__123
v134234_fsdfsd
a1b2c3d4e5

如何从匹配项中删除行v1__23456和?v__123

答案1

^(?!_)           # don't start with _
(?!.*?_$)        # don't end with _
[a-zA-Z]         # the first character must be a letter
[a-zA-Z0-9_]+$   # after that digits and underscores are ok

您以两种不同的方式表达了第一个字符不能是,但这里没有说明中间的_任何内容。__

使用负向先行,可以很简单地表达“一个或多个字母数字字符 或_,不以_或 数字开头,不以 结尾_,并且不允许__任何地方”:

^(?![0-9_]|.*__.*_$|)[0-9A-Z_a-z]+$

如果没有负向前瞻(例如在 awk 或 中grep -E),您可以拆分各个部分:

^[A-Za-z][0-9A-Za-z]*(_[0-9A-Za-z]+)*$

以一个字母开头,然后是零个或多个字母数字,然后可以有下划线,但每个下划线后面必须跟一个或多个字母数字。

答案2

有一种方法可以做到这一点:

perl -nle 'print if /(_)*.*\1/' pattern.txt

输出:

1B2345_
12345-6789
123456789
1_fsdfdfsdf
v_123
v134234_fsdfsd
123456
a1b2c3d4e5

正则表达式/(_)*.*\1/将匹配所有具有两个或多个下划线的行_。只需否定条件即可打印不匹配的行。

答案3

您想查找不包含两个连续下划线的行吗?除非我遗漏了什么,否则这应该有效:

    grep -v '__'

或删除包含任意数量的连续下划线的行:

    grep -v '__*'

或者删除包含多个相邻下划线的行,但保留仅包含单个下划线的行:

    grep -v '___*'

答案4

$ grep -E '^(_?[A-Za-z0-9])*[A-Za-z](_?[A-Za-z0-9])*$' example.txt
1_fsdfdfsdf
v_fsdfsdf_fsdfd
v_123
v134234_fsdfsd
a1b2c3d4e5

相关内容