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

PHP纯文本内容提取难题:无法提取逗号结尾字段

解决PHP提取纯文本中逗号结尾字段的问题

嘿,我看你已经能搞定Keywords、Abstract和https字段的提取了,卡在那些以逗号结尾的字段上对吧?别担心,咱们来一步步解决这个问题。

问题根源

那些逗号结尾的字段(比如name、title、ISSN等)格式是「字段名 + 内容 + 逗号(可能前面带空格)」,你之前的正则没针对这种格式设计,所以匹配不到。另外如果有多个同名字段(比如多个name),还要注意用preg_match_all来捕获所有结果,而不是只取第一个的preg_match。

解决方案代码

我给你修改了脚本,加上了这些逗号结尾字段的提取逻辑,还做了一些鲁棒性优化:

<?php
// 读取文本文件内容
$txt = file_get_contents("in.txt");
// 用更鲁棒的方式分割记录(处理不同换行符和空行前后的空格)
$records = preg_split('/\s*\n\s*\n\s*/', trim($txt));

foreach($records as $key => $record) {
    $data = [];
    
    // 提取编号(调整正则适配可能的空格)
    $id_pattern = '#'.($key+1).'\.\s*(.*?)\s*,\s*\n#';
    preg_match($id_pattern, $record, $id_match);
    $data['id'] = $id_match[1] ?? '';

    // 提取所有name字段(支持多个name的情况)
    $name_pattern = '#name\s*(.*?)\s*,#';
    preg_match_all($name_pattern, $record, $name_matches);
    $data['names'] = $name_matches[1] ?? [];

    // 提取title字段
    $title_pattern = '#title\s*(.*?)\s*,#';
    preg_match($title_pattern, $record, $title_match);
    $data['title'] = $title_match[1] ?? '';

    // 提取sub-title字段
    $sub_title_pattern = '#sub-title\s*(.*?)\s*,#';
    preg_match($sub_title_pattern, $record, $sub_title_match);
    $data['sub_title'] = $sub_title_match[1] ?? '';

    // 提取卷号(匹配行首数字开头的字段)
    $volume_pattern = '#^\s*(\d+)\s*(.*?)\s*,#m';
    preg_match($volume_pattern, $record, $volume_match);
    $data['volume'] = trim($volume_match[1] . ' ' . ($volume_match[2] ?? ''));

    // 提取年份(匹配4位数字开头的行)
    $year_pattern = '#^\s*(\d{4})\s*(.*?)\s*,#m';
    preg_match($year_pattern, $record, $year_match);
    $data['year'] = trim($year_match[1] . ' ' . ($year_match[2] ?? ''));

    // 提取编号(匹配非年份/卷号的数字行)
    $number_pattern = '#^\s*(\d+)\s*(.*?)\s*,#m';
    preg_match($number_pattern, $record, $number_match);
    $data['number'] = trim($number_match[1] . ' ' . ($number_match[2] ?? ''));

    // 提取ISSN字段
    $issn_pattern = '#ISSN\s*(.*?)\s*,#';
    preg_match($issn_pattern, $record, $issn_match);
    $data['issn'] = $issn_match[1] ?? '';

    // 提取https链接(兼容链接前的空格)
    $https_pattern = '#https\s*\:\s*(.*?)\s*\(#';
    preg_match($https_pattern, $record, $https_match);
    $data['https'] = $https_match[1] ?? '';

    // 提取Abstract(匹配到Keywords或记录结尾)
    $abstract_pattern = '#Abstract\:\s*(.*?)\s*(?=Keywords\:|\Z)#s';
    preg_match($abstract_pattern, $record, $abstract_match);
    $data['abstract'] = trim($abstract_match[1] ?? '');

    // 提取Keywords
    $keywords_pattern = '#Keywords\:\s*(.*?)\Z#s';
    preg_match($keywords_pattern, $record, $keywords_match);
    $data['keywords'] = trim($keywords_match[1] ?? '');

    // 这里可以处理提取到的数据,比如存入数据库或者打印调试
    print_r($data);
    echo "-------------------------\n";
}
?>

关键说明

  • 逗号结尾字段的正则:用#字段名\s*(.*?)\s*,#,其中\s*匹配字段名后、逗号前的任意空格,(.*?)非贪婪匹配内容,避免误匹配到后面的字段。
  • 多个同名字段:比如多个name,用preg_match_all可以捕获所有匹配结果,存入数组方便后续处理。
  • 鲁棒性优化:用preg_split分割记录,兼容不同换行符(\n或\r\n)和空行前后的空格;用??运算符处理匹配失败的情况,避免出现Undefined offset报错。
  • 多行匹配:对于卷号、年份这种行首的数字字段,添加m修饰符开启多行模式,让^可以匹配每行的开头。

小提示

如果某些字段的格式有细微差别(比如卷号的数字后面内容特殊),可以根据实际文本调整正则的细节,比如缩小(.*?)的匹配范围,或者添加更精确的字符限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:02:32