【问题标题】:Count matches between specific substrings计算特定子字符串之间的匹配
【发布时间】:2018-10-08 11:27:04
【问题描述】:

我有一个字符串

1AAAAaaa>###_1BBbbbbbbb>###_2CCCCCCCCccccc

数据块以“数字”开头,以>结尾。

我需要计算这些块中有多少小写字母超过大写字母。

作为我想要得到的答案

there are x places between number and >, where lowercase is over 50%.

我了解如何对整个字符串执行此操作,但不适用于单独的区域。

【问题讨论】:

  • 欢迎使用 Stack Overflow 和 Perl 标签。请使用tour 并阅读How to Ask。如果您已经有代码为整个字符串执行此操作,那很好。请edit您的问题并包括在内。我们更倾向于帮助解决一个具体的问题,而不是那些读起来像需求列表的东西。还请更详细地解释您所说的超过 50% 是什么意思。这是相对于所有字符的小写字符数吗?
  • 作为一般建议,听起来您可能希望使用正则表达式来执行此操作。您不必总是在复杂的正则表达式中做所有事情。我可能会将字符串分成多个区域,并完全单独处理每个区域。如果你这样做,你的整个字符串的解决方案应该可以工作。
  • 将问题分解成可以使用my @blocks = $string =~ /.*>/g解决的步骤,剩下的就知道了。

标签: perl substring


【解决方案1】:

您可以使用 split 将字符串的每个目标部分分隔成一个数组。 然后遍历数组并进行计数。

my $string = 'AAAAaaa>1BBbbbbbbb>2CCCCCCCCccccc>3DDDDDDDDDddd>4FFFFfffffff>';

my @targets = split(/(?=\d+\w+>)/, $string);
my $successes = 0;

foreach my $target (@targets){
    my $target_lc = $target =~ tr/a-z//;
    my $target_uc = $target =~ tr/A-Z//;

    if($target_lc > $target_uc){
        $successes++;
    }
}

print $successes;

输出 = 2

【讨论】:

  • 虽然这是一个近似答案,但存在许多问题。 OP 说 “数据块以“数字”开头并以 >“ 结尾,但您的数据块以 > 开头并且数字被忽略。这不必要地扭曲了概念并且没有提供任何优势。您的 @targets 数组包含一个多余的最终元素,其值为 > 显然不包含任何一种大小写的字母。此外,使用s/// 替换字符来计算字符串中的字符是非常规的:规范的方法是使用tr///,如$target_lc = $target =~ tr/a-z// 等。
  • 鲍罗丁是绝对正确的。我已将解决方案编辑为更正确。
  • 您的更新不正确。 tr/// 不使用正则表达式,所以方括号[] 也会被计算在内。
  • 当一个简单的全局捕获就可以完成时,不需要复杂的split 调用:my @targets = $string =~ /\d.*?>/g。您也对数字和> 之间的子字符串的内容一无所知,因此假设它将匹配\w+ 是错误的。 .*?[^>]* 都可以。
猜你喜欢
  • 2014-06-28
  • 1970-01-01
  • 2021-12-01
  • 2021-02-15
  • 2015-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
相关资源
最近更新 更多