仅当字符串包含指定的内容但没有其他内容时,正则表达式匹配

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 以外的字符,则请求将失败。一个空的搅拌器不包含这些。但公平地注意到它

以上是关于仅当字符串包含指定的内容但没有其他内容时,正则表达式匹配的主要内容,如果未能解决你的问题,请参考以下文章

指定开始结束时正则表达式不匹配

正则表达式

用于查找字母字符的前 x 个出现的正则表达式,忽略其他所有内容

正则表达式匹配两个指定字符串之间的内容

使用正则表达式查找幻数

求一个匹配 以指定字符开头,指定字符结尾,中间内容任意的正则表达式