0

Greetings.

I have a function which watches the content of "price" field and updates the string in "cart" field. In "cart" field, string between | characters gets replaced with whatever is typed in "price". My current function only works once while nothing happens on consecutive changes. I know this is not a problem with the event itself because it works fine if I replace the entire field without regex.

This is the format of the "cart" field and 15 needs to be replaced with content from "price" field: {nicepaypal:cart|15|New in 2010}.

$('price').addEvent('keyup', function() {
    var price = $(this).value;
    var currentCartValue = $('cart').value;
    var oldPrice = String(currentCartValue.match(/\|...\|/));
    oldPrice = oldPrice.substring(1, oldPrice.length-1);  // ugly but could not get lookaheads for "between" characters to work properly
    var newCartValue = currentCartValue.replace(oldPrice, price);
    $('cart').value = newCartValue;
});

Another variation does not work either:

newCartValue = currentCartValue.replace(/\|...\|/), '|'+price+'|');

Why is this not working when pressing a key more than once in "price" field. Thank you.

2
  • Moreover, you have to be sure that you always have only 3 characters between |. Assuming that price should always be a number (maybe a float), couldn't you change that to newCartValue = currentCartValue.replace(/\|\d+\.*\d*\|/g, '|'+price+'|');? Commented Apr 6, 2011 at 21:25
  • This was the actual problem: my regex expression was flawed and I changed ... to (.*) Can you post as a main answer so I can upvote you? Commented Apr 6, 2011 at 21:53

3 Answers 3

5

You need to add the g (Global) flag to the regex.

newCartValue = currentCartValue.replace(/\|...\|/g, '|'+price+'|');
Sign up to request clarification or add additional context in comments.

2 Comments

Wow, 5 upvotes for adding the global flag. Almost makes you question the validity of SO. Usually, I get 1 upvote for rendering a complex regex in 2 hours.
@sln: This happens because everyone jumps on a question with an easy-sounding title in order to get an answer in, sees that my answer is already there, and upvotes it. In general, answer upvotes correlate to the easyness of the question. Sad, but true.
2

You have to be sure that you always have only 3 characters between |.

Assuming that price should always be a number (maybe a float), couldn't you change that to

newCartValue = currentCartValue.replace(/\|\d+\.*\d*\|/g, '|'+price+'|');?

If you do not want to check for the number try this

newCartValue = currentCartValue.replace(/\|.*?\|/g, '|'+price+'|');

The ? after .* is crutial, as it makes sure it matches all characters between |, and no | will be found inside.

Comments

2

String.replace will only replace the first instance by default. This can be changed by use of the global (g) flag when using a regex. See use of the g flag below in the first example.

// replace globally
var str1 = "A man is a man is a man."
str1 = str1.replace(/man/g, "woman");
alert(str1);

// replaced only once
var str2 = "A dog is a dog is a dog."
str2 = str2.replace("dog", "cat");
alert(str2);

2 Comments

+1 Because it looks good to me, and its the global flag and you have 119, but are an up-and comer.
Its not that it is replacing only first instance of string, the "cart" was not being matched the second time I press a key because my regex was flawed as pointed by @MPękalski

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.