仅当字符串包含指定的内容但没有其他内容时,正则表达式匹配
Posted
技术标签:
【中文标题】仅当字符串包含指定的内容但没有其他内容时,正则表达式匹配【英文标题】:Regex match only if string contains what is specified but nothing else 【发布时间】:2022-01-09 01:15:41 【问题描述】:我正在尝试在 perl 中实现一个 REGEX,如果字符串包含我指定的任何内容,它就会匹配,但如果字符串包含其他任何内容,即使它还包含我的正则表达式元素,它也必须失败。 例如:
if ($string !~ m/[ACTG]1,/)
die "invalid sequence";
如果我输入 DQJ
作为 s 序列,程序就会死掉。但是,如果我输入 ACH
它不会,因为它至少包含正则表达式模式中的一个元素。
如果字符串包含 A、C、T 或 G 以外的任何内容,我希望匹配失败。
PS:我不熟悉这种情况下的命名法,我将在正则表达式语句中的 // 内称为什么?
【问题讨论】:
您可以省略1,
而不改变正则表达式的工作方式。但是你的问题是什么?
@GuidoFlohr 谢谢!如果字符串包含 ACTG 以外的任何内容,我希望程序终止。
用=~
代替!~
,否定字符类[^ACTG]
,去掉量词,最后检查字符串是否不为空。
或使用锚点 (see the manual)。
您可以使用die 'Invalid sequence' unless $string =~ /[ACTG]+/;
。
【参考方案1】:
使用^
字符定义字符串的开头
和 $
定义结束。
if ($string !~ /^[ACTG]*$/)die "invalid sequence";
【讨论】:
不幸的是,如果我这样实现它,我的匹配几乎总是失败。仅当序列以 A 开头并以 G 结尾或类似的东西时才使用 ^ 和 $ 匹配时才有效? 请注意,这允许AAAA␊
。使用\z
禁止换行。
@Alan 缺少*
(添加)
@ikegami 完美运行!非常感谢。
连同池上建议的\z
,你应该使用\A
作为字符串的绝对开头。 ^
和 $
都具有基于 /m
正则表达式标志的状态的可变含义。【参考方案2】:
您可以确保每个字符都是有效字符。
die if !/^[ACTG]*\z/;
使用更快的tr///:
die if tr/ACTG// != length($_);
或者您可以确保字符串不包含无效字符。
die if /[^ACTG]/;
使用更快的tr///:
die if tr/ACTG//c;
感谢@DavidO 建议 tr///。
【讨论】:
您会考虑在此应用程序中使用带有 /c 的音译吗?tr/ACTG//c
@DavidO。当然。那会更快。已添加。
@brian d foy 您刚刚确定了为什么这不是最佳实践。是的,我可以在这里进行防御性编码,但是“^”更容易被识别,不会添加更多倾斜的牙签,并且遵循 is-different-looks-different 原则。
请注意,所有这些解决方案都将允许空字符串,这可能会或可能不会被 OP 接受。
@pilcrow,如果请求包含 ACGT 以外的字符,则请求将失败。一个空的搅拌器不包含这些。但公平地注意到它以上是关于仅当字符串包含指定的内容但没有其他内容时,正则表达式匹配的主要内容,如果未能解决你的问题,请参考以下文章