【问题标题】:perl match specific number and wordperl 匹配特定的数字和单词
【发布时间】:2019-04-15 02:15:44
【问题描述】:

给定一个文件包括:

const users = [
  {
    name: 'Jeff',
    age: 52,
    gender: 'male'
  },
  {
    name: 'Andy',
    age: 25,
    gender: 'male'
  },
  {
    name: 'Sarah',
    age: 30,
    gender: 'female'
  },
  {
    name: 'Phoebe',
    age: 21,
    gender: 'female'
  },
  {
    name: 'Doris',
    age: 81,
    gender: 'female'
  }
];

我正在尝试匹配“年龄与性别是男性”,但我不知道为什么我的代码不能匹配这个。但它适用于“https://regex101.com/r/cO8lqs/24

while ($line = <FILE>){
    if($line =~ /age:(.*)\,\s*gender: 'male'\}/g){
        print "$1\n"; #output display number only
        print "$line\n";
    }   
}

应该像这样匹配:

age: 52,
gender: 'male'

age: 25,
gender: 'male'

【问题讨论】:

  • &lt;&gt; 默认情况下一次读取一行,看起来您希望它读取多个。
  • 鉴于您的数据结构,进行一些格式化可能会更容易(例如 s/^.*?=\s*// 删除 const users = (根据您的文件进行调整...))并使用JSON 模块而不是使用正则表达式。

标签: perl


【解决方案1】:

你犯了一个大错误和一个小错误。

主要是,您似乎忘记了&lt;FILE&gt; 将从您的文件中读取一行。并且您文件中的每一行都不会与您的正则表达式匹配。您可以通过在循环中打印 $line 的值来验证这一点。

解决此问题的最简单方法是使用$/ 变量。 $/ 是 Perl 的“输入记录分隔符”。它包含 Perl 在读取文件时用来确定记录结束的文本字符串。默认值为\n(这就是&lt;...&gt; 一次读取一行的原因),但我们可以更改它以使其更有用。

$/ = "},\n";

现在,如果你打印$line,你会得到更有用的东西。

但代码仍然不起作用。因为你的正则表达式中的小错误。

您的正则表达式如下所示:

age:(.*)\,\s*gender: 'male'\}

假设结束 } 直接跟在字符串 male 之后。但事实并非如此——它们之间有一个换行符。如果您更改正则表达式以解决此问题,那么它将起作用:

age:(.*)\,\s*gender: 'male'\s*\}

您的代码现在可以工作,但是像这样解析代码相当脆弱。最好建议您删除 const users =,然后使用 JSON 解析器解析其余部分。

【讨论】:

    【解决方案2】:

    你也可以用 Perl-oneliner 来做。我使用 \x27 十六进制来匹配单引号。看看这个

    > perl -ne ' BEGIN {$/="}"} { print $x if /(age:(.+?).*(gender:\s\x27male\x27))/osmg and $x="$1\n" } ' const.txt
    age: 52,
        gender: 'male'
    age: 25,
        gender: 'male'
    >
    

    或更紧凑的。

    > perl -ne ' BEGIN {$/="}"} { print $x if /age:.*gender:\s\x27male\x27/osmg and $x="$&\n" } ' const.txt
    age: 52,
        gender: 'male'
    age: 25,
        gender: 'male'
    >
    

    【讨论】:

    • 您没有帮助 OP,也没有帮助以后可能遇到类似问题的任何人。他的代码 sn-p 很有可能是更大程序的一部分,在这种情况下,您的答案没有用。是的,写单行字有点意思,但我认为这不是一个好的答案。
    • @Dada.. 答案特定于这个输入文件。我从来没有声称它是一个通用的解决方案.. OP 从来没有提到你所说的作为要求并且我的回答很好..请理解上下文然后投反对票.. 或者在你投反对票之前给出你最好的答案。
    • 问题是,任何精通 Perl 以理解您的单行代码的人一开始就不会遇到问题。另外,我并不抱怨您的答案特定于该输入文件这一事实,而是您的答案假设 OP 只想执行他编写的 4 行代码。很可能,它是一个更大程序的一部分,一旦检索到年龄/性别,他就会对它们进行处理。
    • 关于您“在否决其他人之前给出最佳答案”:这绝不是 SO 的规则,而且在 imo 中毫无意义。如果不写我自己的答案,我可以认为你的答案不好。但是,如果您在乎:我阅读了这个问题,考虑了它,写了一条评论,提出了解决该问题的更好方法,阅读了 Dave 的答案,并对其进行了投票。所以我认为我对上下文的理解已经足够好了。在那之后,我看到了你的回答,并写了我的评论来解释我为什么不同意。 => 我不认为我的方法是错误的,我不应该投反对票。
    • 您的假设可能同样错误.. sn-p 可能是大型 bash 程序的一部分,其中 OP 使用 perl 脚本来提取年龄和性别.. 在这种情况下,我的回答很合适,并且这就是 OP 投票的原因..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    相关资源
    最近更新 更多