3

I have some titles that start with # (as they are markdown), and I have the two following rules:

  • titles (#) should have exactly two newlines lines above and one underneath
  • subtitles (##, ### and so forth) should have exactly one blank line above and one below.
  • Titles should takes precedence over subtitles. (If there is two conflicting rules, use the title formatting and ignore subtitles).

NOTE: I'm trying to find all titles that does not conform to these three restrictions.

Below is some examples of good and bad titles

some text 
# Title     | BAD 

## Subtitle | Good (Has two spaces below, is needed for next main title)


# Title     | Good

## Subtitle | Bad
text  

# Title     | Bad

text

After fiddling around with regexp I came up with these expressions:

Main titles: Regexr

((?<=\n{4})|(?<=.\n{2})|(?<=.\n))(# .*)|(# .*)(?=(\n.|\n{3}(?!# )|\n{4}))

Subtitles: Regex

'((?<=\n{3})|(?<=.\n))(##+.*)|(##+.*)(?=\n.|\n{3}(?!# )|\n{4}.)'

However to my great confusion they don't work with pcregrep? Here is the command I tried to run with pcgrep (just for completeness sake):

$ pcregrep -rniM --include='.*\.md' \
     '((?<=\n{3})|(?<=.\n))(##+.*)|(##+.*)(?=\n.|\n{3}(?!# )|\n{4}.)' \
     ~/Programming/oppgaver/src/web

It doesn't work either when I try to just search one file either and I have a couple other expressions that work just fine.

Is there something wrong with my regex, or is it a faulty implementation?

closed as unclear what you're asking by Kusalananda, schily, Jeff Schaller, G-Man, slm Jul 16 '18 at 14:59

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • I kinda sorta see what you're trying to do but this approach is making my head hurt 8-). Which usually means, from my experience, that I'm doing something either wrong or the "hard way". Just sayin...Keep at it though! – slm Jul 15 '18 at 19:26
  • 3
  • 3
    My problem is not the regex, it does what I want it to do. It passes all my test cases, however in the shell it simply outputs nothing... @slm Perhaps an easier solution would be to use perl or something to purge the file for all excess white space, then insert white space matching the conditions above? @steeldriver Hahaha. That very well might be the case. Feel free to suggest other ways than regex to solve the problem though =) – Øistein Søvik Jul 15 '18 at 19:34
  • 1
    I fully agree with the folks mentioning the XY problem. This could be solved with Perl in a way that is more easily understandable by those reading it. – varlogtim Jul 16 '18 at 3:39
  • 3
    All of the requirements should be in the question, not in the comments. – Jeff Schaller Jul 16 '18 at 11:04
1

This solution fixes all unright titles.

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;

With comments:

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

Input

text
# Title
## SubTitle
### SubSubTitle
# Title
## SubTitle
text
### SubSubTitle
# Title
# Title
# Title
## SubTitle
### SubSubTitle

Output

text


# Title

## SubTitle

### SubSubTitle


# Title

## SubTitle

text

### SubSubTitle


# Title


# Title


# Title

## SubTitle

### SubSubTitle

Not the answer you're looking for? Browse other questions tagged or ask your own question.