2

I have a simple code that is separating book title from serial using the ":" as separator. This is really a straight forward solution and should work. On my website it's working but stopping when using german umlauts in the book title. So I created a JSFiddle to find out what's going on but the code breaks whenever I'm using the replace() function.

html:

<div id="title">Die Träne des Fressers: Weiße Königin</div>
Title:<div id="output_title">output title</div>
Serial:<div id="output_serial">output serial</div>

js:

title_input = $("#title").text(); 

title   = title_input.match(/[a-z\s,äöüß-]*.*:/i);
serial  = title_input.match(/:\s?[a-z\s,äöüß-]*/i);

title.replace(/\:/g,'');
//serial = serial.replace(/[:|\.]+/g, "").trim();

$("#output_title").text(title);
$("#output_serial").text(serial);

I do not understand what's going on. Could someone explain it to me?

3
  • 3
    The .replace() method returns a new string. It does not change the original string. Commented Nov 16, 2015 at 17:14
  • 3
    Oh, also, the .match() function always returns an array, not a string. The first element of the array (element 0) will contain the matched substring. Commented Nov 16, 2015 at 17:16
  • I missed that fact, you're perfectly right and thanks for pointing me out that .match() returns an array - this is new to me. Commented Nov 16, 2015 at 20:47

3 Answers 3

3

The problem is that .match() is returning an array not a string as you're expecting. You'll need to check for this and select the matching string (if applicable) before calling .replace().

Currently by adding a bit of logging:

title_input = $("#title").text(); 

title   = title_input.match(/[a-z\s,äöüß-]*.*:/i);
serial  = title_input.match(/:\s?[a-z\s,äöüß-]*/i);
console.log(title.length); // <-- Logging

We can see that title is the following:

["Die Träne des Fressers:", index: 0, input: "Die Träne des Fressers: Weiße Königin"]

For your code to work, you need to get the first element of the title array (if available) before calling .replace():

title_input = $("#title").text(); 

title 	= title_input.match(/[a-z\s,äöüß-]*.*:/i);
serial 	= title_input.match(/:\s?[a-z\s,äöüß-]*/i);

if(title && title.length) {
  title = title[0];  
  title.replace(/\:/g,'');
}

$("#output_title").text(title);
$("#output_serial").text(serial);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="title">Die Träne des Fressers: Weiße Königin</div>
Title:<div id="output_title">output title</div>
Serial:<div id="output_serial">output serial</div>

Extra Note: To ensure you don't get an undefined type error, it's a good idea to ensure that title exists and is not an empty array as noted by the if(title && title.length) line.

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

2 Comments

This is a very good explanation and good example to learn from. Thank you!
I could also convert the array using String(title) - this should also solve the array problem IMHO.
2

Like @Pointy mentioned in comments the match() return an array and The first element of the array (element 0) will contain the matched substring so you have to select first element by addinng [0] :

title   = title_input.match(/[a-z\s,äöüß-]*.*:/i)[0];
serial  = title_input.match(/:\s?[a-z\s,äöüß-]*/i)[0];

Also the replace() method will return the new string generated after replacement, so you have to assign it to your variable :

title = title.replace(/\:/g,'');

hope this helps.

Updated fiddle.

1 Comment

I like the way how you handle the array in this compact notation. You're right I wasn't aware that the return value is an array. Thank you.
1

Variable title exists only when script can find one of this symbols and title isn't string - it's array. You can't use replace on null or on array.

This should works:

var title = $("#title").text(); 
title = title.replace(/[a-z\s,äöüß-]*.*:/i,'');

And if you want to split this string you should use .split(':') function.

Comments

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.