Minoo
Minoo

Reputation: 11

Regex replacement problems

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

Answers (2)

jmcgriz
jmcgriz

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

The fourth bird
The fourth bird

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 -->

Regex demo

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 -->)?

Regex demo

Upvotes: 3

Related Questions