1

我正在尝试将我的个人 wiki 从 Foswiki 转换为 Markdown 文件,然后再转换为 JAMstack 部署。Foswiki 使用平面文件并以以下格式存储元数据:

%META:TOPICINFO{author="TeotiNathaniel" comment="reprev" date="1571215308" format="1.1" reprev="13" version="14"}%

我想使用 git repo 进行版本控制,并且会担心稍后将其链接到文章元数据。此时,我只想将这些块转换为如下所示的内容:

---
author: Teoti Nathaniel
revdate: 1539108277
---

经过一些调整后,我构建了以下正则表达式:

author\=\['"\]\(\\w\+\)\['"\]\(\?\:\.\*\)date\=\['"\]\(\\w\+\)\['"\]

根据regex101这可行,我的两个捕获组包含所需的结果。尝试实际运行它:

perl -0777 -pe 's/author\=\['"\]\(\\w\+\)\['"\]\(\?\:\.\*\)date\=\['"\]\(\\w\+\)\['"\]/author: $1\nrevdate: $2/gms' somefile.txt

让我只有这个:

>

我之前的尝试(如果细节没有按特定顺序中断)看起来像这样并正确执行:

perl -0777 -pe 's/%META:TOPICINFO\{author="(.*)"\ date="(.*)"\ format="(.*)"\ (.*)\}\%/author:$1 \nrevdate:$2/gms' somefile.txt

我认为这是一个转义字符问题,但无法弄清楚。我什至去找了这个工具来确保它们是正确的。

强制我理解这里的方式既低效又令人沮丧,所以我向社区寻求帮助。

4

3 回答 3

2

第一个主要问题是您试图'在程序中使用单引号 ( ),而此时程序正以单引号传递给 shell。

'使用 转义程序中的任何实例'\''\x27如果引号恰好是单个双引号字符串文字或正则表达式文字(就像程序中每个实例的情况一样),您也可以使用。

perl -0777pe's/author=['\''"].../.../gs'
perl -0777pe's/author=[\x27"].../.../gs'
于 2021-05-04T20:08:45.780 回答
1

我会尝试将其分解为一个干净的数据结构,然后对其进行处理。通过将数据处理与打印分开,您可以稍后修改以添加额外的数据。它也使它更具可读性。请看下面的例子

#!/usr/bin/env perl
use strict;
use warnings;
## yaml to print the data, not required for operation
use YAML::XS qw(Dump);
my $yaml;

my @lines = '%META:TOPICINFO{author="TeotiNathaniel" comment="reprev" date="1571215308" format="1.1" reprev="13" version="14"}%';

for my $str (@lines )
{
    ### split line into component parts
    my ( $type , $subject , $data ) = $str =~ /\%(.*?):(.*?)\{(.*)\}\%/;
    ## break data in {} into a hash
    my %info = map( split(/=/),  split(/\s+/, $data) );

    ## strip quotes if any exist
    s/^"(.*)"$/$1/ for values %info;

    #add to data structure
    $yaml->{$type}{$subject} = \%info;
}
## yaml to print the data, not required for operation
print Dump($yaml);

## loop data and print
for my $t (keys %{ $yaml } ) {
    for my $s (keys %{ $yaml->{$t} } ) {
        print "-----------\n";
        print "author: ".$yaml->{$t}{$s}{"author"}."\n";
        print "date: ".$yaml->{$t}{$s}{"date"}."\n";
    }
}
于 2021-05-04T20:36:22.700 回答
0

好的,我一直在玩弄它,将执行减少到一个术语并扩展。我很快就到了这里:

$ perl -0777 -pe 's/author=['\"]\(\\w\+\)['"](?:.*)date=\['\"\]\(\\w\+\)\['\"\]/author\: \$1\\nrevdate\: \$2/gms' somefile.txt

Unmatched [ in regex; marked by <-- HERE in m/author=["](\w+)["](?:.*)date=\["](\w+)[ <-- HERE \"\]/ at -e line 1.

这最终让我来到了这里:

perl -0777 -pe 's/author=['\"]\(\\w\+\)['"](?:.*)date=['\"]\(\\w\+\)['\"]/\nauthor\ $1\nrevdate\:$2\n/gms' somefile.txt

这会产生混乱的输出但可以工作。(注意:输出是概念验证,现在可以在 Python 脚本中使用,以编程方式生成 Markdown 元数据。

感谢您成为我的橡皮鸭,StackOverflow。希望这对某人、某处、某时有用。

于 2021-05-04T19:59:44.733 回答