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

如何使用Perl正则表达式捕获连字符单词中连字符的位置?

解决Perl中捕获连字符单词所有连字符位置的问题

你当前的代码里,正则表达式^(?:[\p{L&}0-9\.\'\/]{1,}([\-])){7,}[\p{L&}0-9\.\'\/]{1,}$无法捕获所有连字符位置,核心原因是重复的捕获组会覆盖之前的匹配结果——每次循环(?:...([\-]))时,捕获组1的内容都会被新匹配的连字符替换,最终只能拿到最后一个连字符的位置。

解决方案1:全局匹配逐个获取连字符位置

直接在单词中全局匹配连字符,每次匹配记录其在单词中的位置,再加上单词在文本中的起始偏移量得到绝对位置:

my $word           = shift (@_);
my $word_start_pos = shift (@_);
my $text           = shift (@_);

# 全局遍历单词中的所有连字符
while ($word =~ /\-/g) {
    my $pos_in_word = $-[0]; # 当前连字符在单词内的起始位置
    my $dash_pos_in_text = $word_start_pos + $pos_in_word;
    
    # 直接字符串比对比正则更高效
    if (substr($text, $dash_pos_in_text, 1) eq '-') {
        load_changes('-', $dash_pos_in_text, 'Dash', ' ', 'Replace');
    }
}

解决方案2:先验证连字符数量再捕获位置

如果需要先确保单词包含至少7个连字符,再处理位置,可以先统计连字符数量,符合条件后再全局匹配:

my $word           = shift (@_);
my $word_start_pos = shift (@_);
my $text           = shift (@_);

# 统计单词中的连字符总数
my $dash_total = () = $word =~ /\-/g;

if ($dash_total >= 7) {
    # 遍历所有连字符位置
    while ($word =~ /\-/g) {
        my $pos_in_word = $-[0];
        my $dash_pos_in_text = $word_start_pos + $pos_in_word;
        
        if (substr($text, $dash_pos_in_text, 1) eq '-') {
            load_changes('-', $dash_pos_in_text, 'Dash', ' ', 'Replace');
        }
    }
}

关键说明

  • /-/g开启全局匹配后,每次调用=~会从上次匹配结束的位置继续查找,配合$-[0]可以获取当前匹配的连字符在$word中的起始索引。
  • 字符串直接比对eq '-'比正则匹配/^[\-]$/更高效,适合单个字符的判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:25:03