#regex #perl #markdown #foswiki
Вопрос:
Я пытаюсь преобразовать свою личную вики-страницу из Foswiki в файлы Markdown, а затем в развертывание JAMstack. Foswiki использует плоские файлы и хранит метаданные в следующем формате:
%META:TOPICINFO{author="TeotiNathaniel" comment="reprev" date="1571215308" format="1.1" reprev="13" version="14"}%
Я хочу использовать репозиторий git для управления версиями и буду беспокоиться о том, чтобы связать это с метатадой статьи позже. На данный момент я просто хочу преобразовать эти блоки во что-то, что выглядит следующим образом:
---
author: Teoti Nathaniel
revdate: 1539108277
---
После небольшой настройки я построил следующее регулярное выражение:
author=['"](\w )['"](?:.*)date=['"](\w )['"]
Согласно регулярному выражению 101, это работает, и мои две группы захвата содержат желаемые результаты. Попытка фактически запустить его:
perl -0777 -pe 's/author=['"](\w )['"](?:.*)date=['"](\w )['"]/author: $1nrevdate: $2/gms' somefile.txt
дает мне только это:
>
Моя предыдущая попытка (которая прерывается, если детали не расположены в определенном порядке) выглядела так и была выполнена правильно:
perl -0777 -pe 's/%META:TOPICINFO{author="(.*)" date="(.*)" format="(.*)" (.*)}%/author:$1 nrevdate:$2/gms' somefile.txt
Я думаю, что это проблема с escape-персонажем, но не могу ее решить. Я даже пошел и нашел этот инструмент, чтобы убедиться, что они верны.
Грубое принуждение меня к пониманию здесь является одновременно неэффективным и разочаровывающим, поэтому я прошу сообщество о помощи.
Комментарии:
1. Совет:
/m
бесполезно, если вы не используете^
или$
Ответ №1:
Первая серьезная проблема заключается в том, что вы пытаетесь использовать одинарную кавычку ( '
) в программе, когда программа передается в оболочку в одинарных кавычках.
Экранируйте любой экземпляр '
в программе с помощью '''
. Вы также можете использовать x27
, если цитата представляет собой один строковый литерал в двойных кавычках или литерал регулярного выражения (как в случае каждого экземпляра в вашей программе).
perl -0777pe's/author=['''"].../.../gs'
perl -0777pe's/author=[x27"].../.../gs'
Ответ №2:
Я бы попытался разбить его на чистую структуру данных, а затем обработать. Разделив обработку данных на печать, вы можете изменить их, чтобы позже добавить дополнительные данные. Это также делает его гораздо более читабельным. Пожалуйста, посмотрите пример ниже
#!/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";
}
}
Ответ №3:
Хорошо, я продолжал дурачиться с этим, сократив выполнение до одного срока и расширив его. Я скоро добрался сюда:
$ 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 $1nrevdate:$2n/gms' somefile.txt
Что дает беспорядочный результат, но работает. (Примечание: Вывод является доказательством концепции, и теперь его можно использовать в скрипте Python для программной генерации метаданных уценки.
Спасибо, что был моим резиновым утенком, StackOverflow. Надеюсь, это кому-нибудь пригодится, где-нибудь, когда-нибудь.
Комментарии:
1. Заменить
perl -0777 -pe
наprintf %s
. Ваша программа не такая, как вы думаете. Вы передаете следующееperl
:s/author=["](w )["](?:.*)date=["](w )["]/nauthor $1nrevdate:$2n/gms
. Обратите внимание на отсутствие одинарных кавычек.