简体   繁体   中英

Javascript Regex for replacing text arrows -> <-

Here is an example of what I am attempting to do:

This is a paragraph of text.  
<-This is some text to be left aligned<-
This is some more text.

This is a paragraph of text.  
                       ->This is some text to be centered<-
This is some more text.

This is a paragraph of text.  
                                        ->This is some text to be right aligned->
This is some more text.

The arrow characters <- -> are being used to specify (by the user) which way they want to align the text. Here's what I've been putting together so far:

var text = "->This is some text to be centered<-";
var center_text = text.match("->(.*)<-");
if(center_text){
    text = '<span style="text-align:center;">'+center_text[1]+'</span>';
    console.log(text);
}

While this does work, it would break if there were two of these situations right after another: ->Text<- ->Text2<-, it would only replace the first -> and the last <- and ignore the two arrows in the middle.

I need the regex to be able to recognize that it should replace every set of these arrows, ie ->Text<- is one replacement and ->Text-> is another replacement. Is this possible in javascript?

UPDATE:

var text = "This is a paragraph.  <-This is left aligned<-.  This is a paragraph.  ->This is center aligned<-.  This is a paragraph.  ->This is right aligned->.  This is a paragraph.  ->This is right aligned->. This is a paragraph. ->This is center aligned<-";
text = text.replace(/<-(.*?)<-/g, '<span style="text-align: left;">$1</span>');
text = text.replace(/->(.*?)<-/g, '<span style="text-align: center;">$1</span>');
text = text.replace(/->(.*?)->/g, '<span style="text-align: right;">$1</span>');

console.log(text);

This is based off of the answers below, but this breaks. Here is what it really turns it into:

This is a paragraph.  <span style="text-align: left;">This is left aligned</span>.  This is a paragraph.  <span style="text-align: right;">This is center aligned<span style="text-align: left;">.  This is a paragraph.  </span>This is right aligned<span style="text-align: right;">.  This is a paragraph.  </span>This is right aligned<span style="text-align: right;">. This is a paragraph. </span>This is center aligned</span>

How to fix this, and is there a more elegant way of doing this?

Thanks in advance, not very good with regex. Sorry did not see answers below before posting this recent updated.

Why are you calling String#match ? You can do that in single String#replace call:

var text = "->Text<- ->Text2<-";
var repl = text.replace(/->(.*?)<-/g, "<center>$1</center>");
//=> "<center>Text</center> <center>Text2</center>"

Because your center, left, and right alignment blocks use the same delimiters, strategies which attempt to match only one type block at a time run the risk of over-eager matching. Consider this example:

-> left ->
<- right <-

Simply applying a rule that replaces ->(.*?)<- with <center>$1</center> will result in:

<center> left ->
</center> right <-

I think you'll have to try to match centered, left, and right-aligned blocks at once. Something like this would work:

var result = 
    text.replace(
        /(<-|->)(.*?)(<-|->)/g,
        function(m, l, c, r) {
            var cls = "";
            if (l == "<-" && r == "<-") {
                cls = "align-left";
            } else if (l == "->" && r == "->") {
                cls = "align-right";
            } else if (l == "->" && r == "<-") {
                cls = "align-center";
            } else if (l == "<-" && r == "->") {
                cls = "align-justify";
            }

            return '<div class="' + cls + '">' + c + '</div>';
        });

See this in action here .

Yup, change your greedy .* to lazy .*? :

var center_text = text.match("->(.*?)<-");

Or you can use something like this as well:

var center_text = text.match("->((?:(?!<-).)*)<-");

That said, I wonder why you are using match when you can use a replace, and you can use three regexes for all the three alignments you have:

var regexc = /->(.*?)<-/g;  // Regex for centre
var regexl = /<-(.*?)<-/g;  // Regex for left
var regexr = /->(.*?)->/g;  // Regex for right
var replacec = "<span style=\"text-align:center;\">'$1'</span>"; // Centre replacement
var replacel = "<span style=\"text-align:left;\">'$1'</span>";   // Left replacement
var replacer = "<span style=\"text-align:right;\">'$1'</span>";  // Right replacement

var results = text.replace(regexc, replacec).replace(regexl, replacel).replace(regexr, replacer);

jsfiddle demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM