Reputation: 11
I am trying to write a regex replacment that will do the following but have tried for several hours to no avail.
I have the following regex: (?:\> \[!anki\]-) ([^\n]+)\n(.+(?:\n(?:^.{1,3}$|^.{4}(?<!<!--).*))*)
with the following replacement: (?:\> \[!anki\]-) ([^\n]+)\n(.+(?:\n(?:^.{1,3}$|^.{4}(?<!<!--).*))*)(\n<!-- end of flashcard -->|\n)
Because I want to achieve the following:
> [!anki]- Title
> Answer
> [!anki]- Title
> Answer
<!-- end of flashcard -->
> [!anki]- Title
> Answer
> Another line
> Another line
> [!anki]- Title
> Answer
^7a6a36
To become this:
> [!anki]- Title
> Answer
<!-- end of flashcard -->
> [!anki]- Title
> Answer
<!-- end of flashcard -->
> [!anki]- Title
> Answer
> Another line
> Another line
<!-- end of flashcard -->
> [!anki]- Title
> Answer
^7a6a36
<!-- end of flashcard -->
i.e. if "<!-- end of flashcard --> is not present then add it and if some line of text after the flashcard begins with "^" and then some text then it should be placed underneath the <!-- end of flashcard --> (the ^7a6a36).
If this is better done with multiple regex replacements instead of one then thats fine.
Note im using javascript regex with multiline mode on
Thank you
Upvotes: 1
Views: 101
Reputation: 3368
If the sample input is fully accurate to your data, this is a quick and dirty way to get it done since all you care about is the space between the flashcards:
(\w)[\s>]+(\[!anki\])
replaced with
$1\n<!-- end of flashcard -->\n\n\n$2
The matching regex identifies a single word character followed by only whitespace or the >
character that shows up at the beginning of lines until it hits an [!anki]
, in which case you can add some line breaks and an <!-- end of flashcard -->
into that space
Upvotes: 0
Reputation: 163577
You could capture what is before <!-- end of flashcard -->
and then optionally match it at the end so that it is not present after the replacement to prevent duplicate lines.
(> \[!anki]- .+(?:\n(?!<!--).+)*)(?:\n<!-- end of flashcard -->)?
The pattern matches:
(
Capture group 1
> \[!anki]- .+
Match > [!anki]-
and 1+ times any character without a newline(?:\n(?!<!--).+)*
Optionally repeat matching a newline, then assert not <!--
directly to the right and match 1+ times any character)
Close group 1(?:\n<!-- end of flashcard -->)?
Optionally match a newline and <!-- end of flashcard -->
Replace using capture group 1 denoted by $1
:
$1\n<!-- end of flashcard -->
Using JavaScript:
const regex = /(> \[!anki]- .+(?:\n(?!<!--).+)*)(?:\n<!-- end of flashcard -->)?/g;
const str = `> [!anki]- Title
> Answer
> [!anki]- Title
> Answer
<!-- end of flashcard -->
> [!anki]- Title
> Answer
> Another line
> Another line
> [!anki]- Title
> Answer
^7a6a36`;
const result = str.replace(regex, `$1\n<!-- end of flashcard -->`);
console.log(result);
Or an alternative matching lines that start with >
or ^
(> \[!anki]- .+(?:\n[>^].*)*)(?:\n<!-- end of flashcard -->)?
Upvotes: 3