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

如何在Perl脚本中用RegEx提取<ix:hidden>标签间的代码

Perl脚本提取ix:hidden标签内容的正则问题修复

问题场景

需要提取<ix:hidden>与</ix:hidden>标签之间的代码,目标HTML片段如下:

<ix:hidden>
<ix:nonNumeric contextRef="Duration_4_1_2021_To_3_31_2022_IlKaMcQ2N0C41UxW3xo4zg" name="dei:DocumentType" id="Tc_evMsUKdlCEyCZtbxEMZIxg_1_1">DEF 14A</ix:nonNumeric>
<ix:nonNumeric contextRef="Duration_4_1_2021_To_3_31_2022_IlKaMcQ2N0C41UxW3xo4zg" name="dei:AmendmentFlag" id="Tc_nHcapE52UUqrWD0pLkbdag_2_1">false</ix:nonNumeric>
<ix:nonNumeric contextRef="Duration_4_1_2021_To_3_31_2022_IlKaMcQ2N0C41UxW3xo4zg" name="dei:EntityRegistrantName" id="Tc_ZXMW19KSmk2TfvdhMCMr_A_3_1">Walter Hamscher Co Number One</ix:nonNumeric>
<ix:nonNumeric contextRef="Duration_4_1_2021_To_3_31_2022_IlKaMcQ2N0C41UxW3xo4zg" name="dei:EntityCentralIndexKey" id="Tc_MybzAywpbUCU3LEGZc_Ftg_4_1">0000990667</ix:nonNumeric>
</ix:hidden>

用户编写的Perl脚本中,正则表达式未匹配到目标内容,原脚本如下:

use strict;
use warnings;

my @ar_sp;
my $string;
my @ar_out;

# Source File 
my $src = 'iXBRL-Tagged_tm213138-13_def14a.htm';

# open source file for reading
open(FHR, '<', $src);
  
# Destination File
my $des = 'output.txt';

# Open new file to write
open(FHW, '>', $des);
  
  
print("Copying content from $src to $des\n");
@ar_sp = <FHR>;

# Copy data from one file to another.
foreach $string ( @ar_sp ) 
{
    if ($string =~ m/<ix:hidden>(.*?)<\/ix:hidden>/)
    {
        print "Yes" . "\n";
        $string =~ m/<ix:hidden>(.*?)<\/ix:hidden>/;
        print FHW $string;
    }
    
}

# Closing the filehandles
close(FHR);
close(FHW);
   
print "File content copied successfully!\n";

问题原因

  1. 逐行读取导致匹配失败:原脚本按行读取文件,但<ix:hidden>标签内容跨了多行,单行中不存在完整的<ix:hidden>...</ix:hidden>标签对,正则自然无法匹配。
  2. 正则未处理换行符:默认情况下,Perl正则中的.不会匹配换行符,即使标签逻辑上是连续块,.*?也无法覆盖多行内容。
  3. 输出错误:即使匹配成功,脚本输出的是原行内容,而非捕获到的标签间代码。

修复方案

核心修改点

  • 读取整个文件内容,而非逐行读取,确保能获取完整的标签块。
  • 给正则添加/s修饰符,让.匹配换行符,支持跨行匹配。
  • 捕获标签间的内容并写入输出文件,而非原字符串。

修正后的脚本

use strict;
use warnings;

# 文件路径
my $src = 'iXBRL-Tagged_tm213138-13_def14a.htm';
my $des = 'output.txt';

# 读取整个文件内容
open(my $fh_in, '<', $src) or die "无法打开源文件: $!";
local $/; # 取消输入记录分隔符,一次性读取全部内容
my $content = <$fh_in>;
close($fh_in);

# 提取<ix:hidden>标签间的内容
if ($content =~ m/<ix:hidden>(.*?)<\/ix:hidden>/s) {
    my $hidden_content = $1;
    
    # 写入输出文件
    open(my $fh_out, '>', $des) or die "无法打开输出文件: $!";
    print $fh_out $hidden_content;
    close($fh_out);
    
    print "标签内容已成功提取到 $des\n";
} else {
    print "未找到匹配的<ix:hidden>标签\n";
}

关键说明

  • local $/:临时取消Perl的输入记录分隔符(默认是换行符),这样<$fh_in>会一次性读取整个文件的所有内容。
  • /s修饰符:让正则中的.匹配包括换行符在内的所有字符,确保跨行的标签内容能被完整捕获。
  • 捕获分组$1:对应正则中(.*?)匹配到的内容,也就是<ix:hidden>和</ix:hidden>之间的代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:55:21