【问题标题】:Perl regex replacement in file skips newlines文件中的 Perl 正则表达式替换跳过换行符
【发布时间】:2015-08-10 06:31:52
【问题描述】:

我目前正在尝试格式化文本以用于 pandoc,但我的正则表达式替换不起作用。 到目前为止,这是我的代码:

#Importing the file
my $filename = 'example.md';
my $file = path($filename);
my $data = $file ->slurp_utf8;

#Placing code blocks into an array and replacing them in the file
my @code_block_values;
my $i = 0;
while($i > 50) {
    @code_bock_values[$i] = ($data =~ /\n\t*```[^`]+(```){1}\n/);
    $data =~ s/\n\t*```[^`]+(```){1}\n/(code_block)/;
    $i = $i + 1;
}

#Replacing the code blocks
$i = 0;
while($i < 50) {
    $data =~ s/\(code_block\)/$code_block_values[$i]/;
    $i = $i + 1;
}
print $data;

$file->spew_utf8( $data );

我意识到这可能不是最有效的方法,但现在我只是想让它发挥作用。

基本上,我使用 github 风格的 markdown 来输入我的笔记,然后尝试使用 pandoc 将其转换为 pdf 文件。我正在预先进行一些其他格式化,但我必须先提取代码块(由三个反引号(``)分隔。)

以下是代码块的示例代码块:

```bash
#!/bin/bash
echo "Enter a number"
read count
if [ $count -eq 100 ]
then
  echo "Example-3: Count is 100"
elif [ $count -gt 100 ]
then
  echo "Example-3: Count is greater than 100"
else
  echo "Example-3: Count is less than 100"
fi
```

据我所知,正则表达式正在捕获我需要的所有内容(由在线正则表达式测试器测试),但 Perl 仅在某些点插入换行符,特别是换行符后跟一个制表符。

前面的例子翻译成:

```bash #!/bin/bash echo "Enter a number" read count if [ $count -eq 100 ] then
  echo "Example-3: Count is 100" elif [ $count -gt 100 ] then
  echo "Example-3: Count is greater than 100" else
  echo "Example-3: Count is less than 100" fi
```

如您所见,标签也被完全删除。我从 atom 复制了所有文件内容,并且从编辑器复制了不同长度的选项卡(不确定这会有所不同。)我在 vim 中编辑了 shell 脚本,但在 atom 中编辑了注释自己。

我是 Perl 新手,因此我们将不胜感激。

【问题讨论】:

  • 第一个while 循环似乎永远不会运行,因为$i = 0 它不能大于50
  • 正则表达式 (```){1} 部分的目的是什么?为什么不直接使用```?和 @code_bock_values[$i] 应该用括号括起来,以便捕获任何捕获组
  • 抱歉,我错过了 @code_bock_values[$i] 前面的 @ 符号。也许这是一个错字?应该是$ 似乎更合理
  • 你在用什么系统?
  • 这些都不起作用,甚至运行时没有错误(使用严格;使用警告;)。从表面上看,您似乎只是想去掉分隔符 ``` 显示您的输入和预期输出,或者添加更多示例来说明您正在尝试做的事情。

标签: regex perl


【解决方案1】:

我的猜测:

#!/usr/bin/perl
use strict;
use warnings;

# Slurps DATA after __END__ into a scalar
my $data = do { local $/; <DATA> };

my @code_block_values;

# Extract and replace code blocks with '(code_block)'
while ($data =~ s/ (``` .*? ```) /(code_block)/xs) {
    push @code_block_values, $1;
}

printf "\n--| Replaced:\n%s", $data;

# Restore '(code_block)' with actual content
$data =~ s/ \(code_block\) / shift @code_block_values /xge;

printf "\n--| Restored:\n%s", $data;

__END__

```bash
#!/bin/bash
echo "Enter a number"
read count
if [ $count -eq 100 ]
then
  echo "Example-3: Count is 100"
elif [ $count -gt 100 ]
then
  echo "Example-3: Count is greater than 100"
else
  echo "Example-3: Count is less than 100"
fi
```

```perl
#!/usr/bin/perl
print "Hello World\n";
```

输出:

--| Replaced:

(code_block)

(code_block)

--| Restored:

```bash
#!/bin/bash
echo "Enter a number"
read count
if [ $count -eq 100 ]
then
  echo "Example-3: Count is 100"
elif [ $count -gt 100 ]
then
  echo "Example-3: Count is greater than 100"
else
  echo "Example-3: Count is less than 100"
fi
```

```perl
#!/usr/bin/perl
print "Hello World\n";
```

如果您想了解有关 Perl 正则表达式的更多信息,perlreperlretut 是不错的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多