27

The Prob: I get an AJAX response (JSON or plaintext with line breaks). Each item of the response should be checked via RegEx to find out whether it matches to user-definded patter or not.

Example:

Ajax Response (plain-text)

"Aldor
Aleph
Algae
Algo
Algol
Alma-0
Alphard
Altran"

User-pattern:

/^Alg/ig.test(responseItem)

RegExp Results should look like:

Aldor   // false
Aleph   // false
Algae   // true
Algo    // true
Algol   // true
Alma-0  // false
Alphard // false
Altran  // false

But each time i get different (and kinda weired) results... e.g. (/^alg/ig.test("Algo") => false)

My code:

HTML

...
<form>
  <input id="in" />
</form>
<div id="x">
  Aldor
  Aleph
  Algae
  Algo
  Algol
  Alma-0
  Alphard
  Altran
</div><button id="checker">check!</button>
...

JavaScript (jQuery 1.6.2)

$(function(){
    var $checker = $('#checker');

    $checker.click(function(ev){
        var inputFieldVal = $.trim($('#in').val());
        console.log(inputFieldVal); // Alg
        var regExpPattern = '^'+inputFieldVal,
            re = new RegExp(regExpPattern, 'igm');
        onsole.log(re); // /^Al/gim
        // Get text out of div#x
        var text = $('#x').text();
        // Trim and 'convert' to an array...
            text = $.trim(text).split('\n');
        console.log(text); // ["Aldor", "Aleph", "Algae", "Algo", "Algol", "Alma-0", "Alphard", "Altran"]

        for (var index=0, upper=text.length;index<upper;++index) {
            console.log(
               re.test(text[index]),
               text[index]
             );
        }
    });
})

Console OUTPUT:

/^Alg/ig => should match each item which starts with Alg

false "Aldor"
false "Aleph"
true "Algae"
false "Algo" //Why ? O.o
true "Algol"
false "Alma-0"
false "Alphard"
false "Altran"

/^Al/ig => should match each item because every item start with Al

true "Aldor"
false "Aleph" //Why ? O.o
true "Algae"
false "Algo" //Why ? O.o
true "Algol"
false "Alma-0" //Why ? O.o
true "Alphard"
false "Altran" //Why ? O.o

Any suggestions?

6
  • 1
    Does executing /^alg/ig.test("Algo") literally also give you false? Commented Jul 31, 2011 at 18:56
  • P.S. The point of whole ting is that I want not only match item(s) from the response, but also be able to collect them. Commented Jul 31, 2011 at 19:01
  • @pimvdb, no. /^alg/ig.test("Algo") returns true Commented Jul 31, 2011 at 19:05
  • Could you please post the result of text if you map it first with this function? text = text.map(function(v) {var res = [];for(var i=0;i<v.length;i++){res.push(v.charCodeAt(i))}return res;}) It converts the string array to their respective character codes, to highlight non-printable characters. Commented Jul 31, 2011 at 19:07
  • Trying printing the length of the strings too, in case, somehow, there are 'invisible' characters. Commented Jul 31, 2011 at 19:12

4 Answers 4

75

This is a common behavior that the the exec or test methods show when you deal with patterns that have the global g flag.

The RegExp object will keep track of the lastIndex where a match was found, and then on subsequent matches it will start from that lastIndex instead of starting from 0.

For example:

var re = /^a/g;
console.log(re.test("ab")); // true, lastIndex was 0
console.log(re.test("ab")); // false, lastIndex was 1

Remove the g flag from your pattern, since you are looking just for a single match (you are testing each line separately).

Sign up to request clarification or add additional context in comments.

3 Comments

What about 3rd execution? why is it again true?
@gumkins, because after reaching the end of the string, the lastIndex starts again from 0.
still not clear, why the end of the string was reached after second run and not after third or fourth?
5

You have to remove the global flag "g".

Comments

0

try this~

var str = "Aldor\rAleph\rAlgae\rAlgo\rAlgol";
var myregexp = /^alg.*$/img;
var match = myregexp.exec(str);
while (match != null) {
    for (var i = 0; i < match.length; i++) {
        alert(match[i]);
    }
    match = myregexp.exec(str);
}

Comments

0

it Was the white space that was not matching it:

try this:

$(function(){
var $checker = $('#checker');

$checker.click(function(ev){
    var inputFieldVal = $.trim($('#in').val());
    console.log(inputFieldVal); // Alg
    var regExpPattern = '^'+inputFieldVal,
        re = new RegExp(regExpPattern, 'igm');
    console.log(re); // /^Al/gim
    // Get text out of div#x
    var text = $('#x').text();
    // Trim and 'convert' to an array...
        text = $.trim(text).split('\n');
    console.log(text); // ["Aldor", "Aleph", "Algae", "Algo", "Algol", "Alma-0", "Alphard", "Altran"]

    for (var index=0, upper=text.length;index<upper;++index) {
        console.log(
           re.test(text[index].trim()),
           text[index]
         );
    }
});

})

here is jsfiddle:

http://jsfiddle.net/9Gqw2/

1 Comment

It seems to have the same weird-prob as my script. I just tested your version an get the same result....

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.