You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Perl正则表达式验证保龄球得分字符串?

保龄球得分字符串的Perl正则验证方案

纯正则表达式方案(依赖Perl高级特性)

可以用一个正则表达式整合所有校验规则,包括帧数量、前9帧规则和第10帧规则。注意该方案需要启用Perl的re 'eval'特性,因为用到了嵌入式代码断言。

use re 'eval'; # 必须启用该特性才能使用嵌入式代码断言

my $gs = 'X-91-55-72-X-X-X-90-82-91X';
my $valid = 0;

if ($gs =~ /\A(?:(?:X|\d{2}(?<=(\d)\d)(?{ $1 + $^N <= 10 }))-){9}(?:XXX|XX\d|X\d{2}(?<=(\d)\d)(?{ $2 + $^N <= 10 })|\d{2}(?<=(\d)\d)(?{ $3 + $^N < 10 })|\d{2}(?<=(\d)\d)(?{ $4 + $^N == 10 })(?:X|\d))\z/) {
    $valid = 1;
}

print $valid ? "有效" : "无效";

正则拆解

  1. 前9帧匹配:(?:(?:X|\d{2}(?<=(\d)\d)(?{ $1 + $^N <= 10 }))-)

    • X:匹配单字符的全中帧
    • \d{2}(?<=(\d)\d)(?{ $1 + $^N <= 10 }):匹配两个数字,通过后向捕获组和嵌入式代码校验两数之和≤10($1是第一个数字,$^N是第二个数字)
    • 整个前9帧部分重复9次,每次后接分隔符-
  2. 第10帧匹配:(?:XXX|XX\d|X\d{2}(?<=(\d)\d)(?{ $2 + $^N <= 10 })|\d{2}(?<=(\d)\d)(?{ $3 + $^N < 10 })|\d{2}(?<=(\d)\d)(?{ $4 + $^N == 10 })(?:X|\d))

    • XXX:三次全中场景
    • XX\d:两次全中加0-9数字场景
    • X\d{2}(?<=(\d)\d)(?{ $2 + $^N <= 10 }):一次全中加两数之和≤10的数字场景
    • \d{2}(?<=(\d)\d)(?{ $3 + $^N < 10 }):两数之和小于10的无补投场景
    • \d{2}(?<=(\d)\d)(?{ $4 + $^N == 10 })(?:X|\d):两数之和等于10的补中场景,后面接全中或数字

拆分校验方案(可读性更强)

如果不想依赖Perl的高级正则特性,可以先拆分帧,再逐个校验规则,可读性和可调试性更好:

my $gs = 'X-91-55-72-X-X-X-90-82-91X';
my $valid = 0;

# 拆分帧
my @frames = split /-/, $gs;

# 校验帧数量是否为10
if (@frames == 10) {
    my $all_valid = 1;

    # 校验前9帧
    for my $frame (@frames[0..8]) {
        if ($frame ne 'X') {
            # 必须是两个数字
            unless ($frame =~ /^(\d)(\d)$/) {
                $all_valid = 0;
                last;
            }
            # 校验两数之和≤10
            unless ($1 + $2 <= 10) {
                $all_valid = 0;
                last;
            }
        }
    }

    # 校验第10帧
    if ($all_valid) {
        my $tenth = $frames[9];
        if (
            $tenth =~ /^XXX$/ ||
            $tenth =~ /^XX\d$/ ||
            ($tenth =~ /^X(\d)(\d)$/ && $1 + $2 <= 10) ||
            ($tenth =~ /^(\d)(\d)$/ && $1 + $2 < 10) ||
            ($tenth =~ /^(\d)(\d)(X|\d)$/ && $1 + $2 == 10)
        ) {
            $valid = 1;
        }
    }
}

print $valid ? "有效" : "无效";

方案说明

  1. 先通过split /-/拆分所有帧,校验数量是否为10
  2. 遍历前9帧,每帧要么是X,要么是两个数字且和≤10
  3. 单独校验第10帧,匹配所有合法场景

内容的提问来源于stack exchange,提问作者rollstreet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:15:04