1

I have a string like this:

var str = " this is a [link][1]
            [1]: http://example.com
            and this is a [good website][2] in my opinion
            [2]: http://goodwebsite.com
            [3]: http://example.com/fsadf.jpg
            [![this is a photo][3]][3]
            and there is some text hare ..! ";

Now I want this:

var newstr = "this is a [link][1]
              and this is a [good website][2] in my opinion
              [![this is a photo][3]][3]
              and there is some text hare ..!


                [1]: http://example.com
                [2]: http://goodwebsite.com
                [3]: http://example.com/fsadf.jpg"

How can I do that?


In reality, that variable str is the value of a textarea ... and I'm trying to create a markdown editor .. So what I want is exactly the same with what SO's textarea does.


Here is my try:

/^(\[[0-9]*]:.*$)/g to select [any digit]: in the first of line

And I think I should create a group for that using () and then replace it with \n\n $1

stack
  • 10,280
  • 19
  • 65
  • 117

2 Answers2

2

try this:

strLinksArray = str.match(/(\[\d+\]\:\s*[^\s\n]+)/g);
strWithoutLinks = str.replace(/(\[\d+\]\:\s*[^\s\n]+)/g, ''); //removed all links

Here you will get links as array and string without links then do whatever changes you want.

Vegeta
  • 1,319
  • 7
  • 17
1

You can use

var re = /^(\[[0-9]*]:)\s*(.*)\r?\n?/gm;                // Regex declaration
var str = 'this is a [link][1]\n[1]: http://example.com\nand this is a [good website][2] in my opinion\n[2]: http://goodwebsite.com\n[3]: http://example.com/fsadf.jpg\n[![this is a photo][3]][3]\nand there is some text hare ..!';
var links = [];                                      // Array for the links
var result = str.replace(re, function (m, g1, g2) {  // Removing the links
  links.push("  " + g1 + " " + g2);                        // and saving inside callback
 return "";                                   // Removal happens here 
});
var to_add = links.join("\n");                   // Join the links into a string
document.getElementById("tinput").value = result + "\n\n\n" + to_add; // Display
<textarea id="tinput"></textarea>

See regex demo at regex101.com.

Regex explanation:

  • ^ - start of line (due to the /m modifier)
  • (\[[0-9]*]:) - Group 1 (referred to as g1 in the replace callback) matching...
    • \[ - opening square bracket
    • [0-9]* - zero or more digits
    • ] - closing square bracket
    • : - a colon
  • \s* - zero or more whitespace
  • (.*) - Group 2 matching (g2) zero or more characters other than newline
  • \r?\n? - one or zero \r followed by one or zero \n
  • /gm - define global search and replace and ^ matches line start instead of string start
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Perfect ..! Just one thing .. How can I add two spaces behind `[1]:`, `[2]:`, `[3]:` ? – stack Jan 22 '16 at 07:36
  • Use 2 capturing groups. – Wiktor Stribiżew Jan 22 '16 at 07:39
  • Very thanks, but have you updated your fiddle? because there isn't two spaces before `[number]:` in your fiddle – stack Jan 22 '16 at 07:48
  • 1
    Aha, you say *before* now, I understood *behind* as *after* :) I updated the answer to reflect that. – Wiktor Stribiżew Jan 22 '16 at 07:55
  • And as a consult: When user clicks of link-icon *(in the toolbar of editor)*, I will add a link-pattern for him .. Now I need to create a new number of his new link, like `[4]` *(if the last link is `[3]`)*. So [I get the biggest number of textarea-value](http://stackoverflow.com/questions/34912624/how-to-get-biggest-number-in-textarea#34912697) and increase it and use it for new link. Is this algorithm ok? Or is there any better alternative? – stack Jan 22 '16 at 08:06
  • 1
    If you keep the array of links on a global level, you won't have to look for the "biggest number", you will have it in `links.length`. – Wiktor Stribiżew Jan 22 '16 at 08:19
  • Sorry to ping you again, Just one thing, your regex works as well, all fine .. But I think we can add `$` to make it more accurate. I mean: select `[anydigit]:` for first of line until end of that line `$`. Am I right? or `$` is useless in this case? – stack Jan 22 '16 at 08:47
  • 1
    `.` does not match a newline. The greedy `.*` subpattern will always match up to the end of the line and stop at the first newline symbol. Thus, it is redundant. – Wiktor Stribiżew Jan 22 '16 at 08:50
  • May you please tell me how can I define this `\s*` as just {zero-space or one-space or - two-spaces or three-spaces}? *(A range between 0-3 spaces)* – stack Jan 22 '16 at 21:15
  • 1
    [*Limiting quantifier*](http://www.regular-expressions.info/repeat.html#limit) to the rescue: `\s{0,3}` will match 0 to 3 whitespaces. – Wiktor Stribiżew Jan 22 '16 at 21:18
  • I don't know how should I say *thanks* :-) You answer quickly .. and always know the answer of my question, and always you are there!, Lemme ask do you need sleep? `;-)` ...! Anyway thanks buddy, I learned a lot of things from you today .. – stack Jan 22 '16 at 21:21
  • I am about to go to bed. You may upvote one of my other [JS answers that have positive votes](http://stackoverflow.com/search?tab=votes&q=user%3a3832970%20%5bjavascript%5d%20%5bregex%5d) to thank for my extra hints :) – Wiktor Stribiżew Jan 22 '16 at 21:29