#
で始まるタイトルがいくつかあり(マークダウンであるため)、次の2つのルールがあります。
#
)は、正確に上に2行、下に1行必要です。##
、###
など)には正確にが必要です上と下に1行の空白行。注:これらの3つの制限に準拠していないすべてのタイトルを見つけようとしています。
以下は良いタイトルと悪いタイトルのいくつかの例です
some text
# Title | BAD
## Subtitle | Good (Has two spaces below, is needed for next main title)
# Title | Good
## Subtitle | Bad
text
# Title | Bad
text
正規表現をいじった後、私はこれらの表現を思いついた:
((?<=\n{4})|(?<=.\n{2})|(?<=.\n))(# .*)|(# .*)(?=(\n.|\n{3}(?!# )|\n{4}))
'((?<=\n{3})|(?<=.\n))(##+.*)|(##+.*)(?=\n.|\n{3}(?!# )|\n{4}.)'
しかし、私の大きな混乱には、それらはpcregrep
では機能しませんか? pcgrep
で実行しようとしたコマンドは次のとおりです(完全を期すため)。
$ pcregrep -rniM --include='.*\.md' \
'((?<=\n{3})|(?<=.\n))(##+.*)|(##+.*)(?=\n.|\n{3}(?!# )|\n{4}.)' \
~/Programming/oppgaver/src/web
1つのファイルを検索しようとしても機能せず、他にも問題なく機能する式がいくつかあります。
私の正規表現に何か問題がありますか、それとも実装に問題がありますか?
このソリューションは、すべての正しくないタイトルを修正します。
sed -r '
:loop; N; $!b loop
s/\n+(#[^\n]+)/\n\n\1/g
s/(#[^\n]+)\n+/\1\n\n/g
s/\n+(#[^\n#]+)/\n\n\n\1/g
' input.txt;
コメント付き:
sed -r '
### put all file into the pattern space,
# in other words, merge all lines into one line
:loop; N; $!b loop;
### first traversal of the pattern space
# searches the line with "#" sign (all cases matches - Titles, SubTitles, etc),
# takes all its upper empty lines
# and converts them to the one empty line
s/\n+(#[^\n]+)/\n\n\1/g;
### second traversal of the pattern space
# again, searches the line with "#" sign, take all its bottom empty lines
# and converts them to the one empty line
s/(#[^\n]+)\n+/\1\n\n/g;
### third traversal of the pattern space
# searches the single "#" sign (Titles only),
# takes all its upper newlines (at this moment only two of them are there,
# because of previous substitutions)
# and converts them to three newlines
s/\n+(#[^\n#]+)/\n\n\n\1/g
' input.txt
入力
text
# Title
## SubTitle
### SubSubTitle
# Title
## SubTitle
text
### SubSubTitle
# Title
# Title
# Title
## SubTitle
### SubSubTitle
出力
text
# Title
## SubTitle
### SubSubTitle
# Title
## SubTitle
text
### SubSubTitle
# Title
# Title
# Title
## SubTitle
### SubSubTitle