admin管理员组

文章数量:1419243

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, i.e. ->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.

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, i.e. ->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.

Share Improve this question edited Sep 29, 2013 at 16:51 klye_g asked Sep 29, 2013 at 16:32 klye_gklye_g 1,2426 gold badges32 silver badges55 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 5

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

本文标签: Javascript Regex for replacing text arrows gt ltStack Overflow