Convert slug variable to title text with javascript - javascript

I'm trying to do something that would be similar to turning a url slug-like variable into text that could be used for a title.
So, I have a variable for example that is like this:
var thisID = 'athlete-profile';
function myFunc(thisID) {
// i need to use thisID as the id and href in a loop that generates a string of <li><a>'s\
function makeTitle(thisID) {
// convert thisID to text so for this example it would return 'Athlete Profile'
return 'Athlete Profile';
}
for () {
var str = '<li id="'+thisID+'">'+makeTitle(thisID)+'';
}
// make sense?
}
I'd like to not use a regex to do this if possible somehow, but I don't think there's a way to do it without one. So any one who knows how to do this type of thing let me know, it would be a great help.
Thanks

I would advise you to use regular expression. But if you really don't want to use regular expressions, the solution below would work for simple cases. Feel free to modify it as you like it.
function makeTitle(slug) {
var words = slug.split('-');
for (var i = 0; i < words.length; i++) {
var word = words[i];
words[i] = word.charAt(0).toUpperCase() + word.slice(1);
}
return words.join(' ');
}
console.log(
makeTitle("athlete-profile")
)

function titleize(slug) {
var words = slug.split("-");
return words.map(function(word) {
return word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
}).join(' ');
}
console.log(titleize("athlete-profile"))
It works pretty simply:
It splits the string by - into words.
It maps each word into title case.
It joins the resulting words with spaces.

Do it in one line:
'athlete-profile'.split("-").join(" ").replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()})
Output: Athlete Profile

The makeTitle() part of your question can be implemented something like this:
function makeTitle(thisID) {
return thisID.replace(/-/g, " ").replace(/\b[a-z]/g, function() {
return arguments[0].toUpperCase();
});
}
console.log(makeTitle("athlete-profile"))
The first .replace() changes all hyphens to spaces, and then the second .replace() takes any lower-case letter that follows a word boundary and makes it upper-case.
(For more information see the MDN doco for .replace().)
As far as doing it without using regular expressions, I'm not sure why you'd specifically want to avoid them, especially when the required expressions are pretty simple in this case (especially if you do the hyphen to space and first letter capitalisation in two steps as shown above). But there are endless ways to do this without regex using various combinations of JavaScript's string manipulation methods.

Do it like this
let someString = 'im a string';
console.log(someString.replace(/-/g, ' ')
.replace(/\w\S*/g, function (txt) {
return
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
})
)
Output: Im A String

Short and great way:
const slugToText = (slug) => {
return slug.toLowerCase().replace(/-/g,' ')
}

Much Simplified answer
we can use String.prototype.replaceAll method to easily achieve this
function convertSlugToString(slug) {
return slug.replaceAll("-", " ");
}
incase you want to make sure the output is all lowercase then you can do the following
function convertSlugToString(slug) {
return slug.toLowerCase().replaceAll("-", " ");
}
Additional info:
String.prototype.replaceAll() is a ES2021 feature and it also has a great browser support with 93.64% global coverage, click here for more info
if you want to support IE then refer to the other answers

Related

Trying to get into replace() instances such as "34-45"

I'm trying to figure out a way to use the replace() function to find strings such as "23-34". So far Iv'e been using the following code for similar purposes, and Id'e like to keep using the function replace (nevermind that it doesn't do anything yet).
function Work() {
function PleaseWork(match) {
var x = +match + 408;
x = ' ' + x;
return x;
}
document.getElementById("InputText").value = document.getElementById("InputText").value.replace(/\s+\d+/g, PleaseWork);
}
Iv'e tried to replace the expression /\s+\d+/g with /\d+\-\d+/g. But unfortunately that won't run or won't result in taking away the instances I need it to take.
Any advises?
I hope this is a valid answer:
function Work() {
function PleaseWork(match) {
// this is your array: match.split('-')
return '[' + match.split('-') + ']';
}
document.getElementById("InputText").value = document.getElementById("InputText").value.replace(/\d+-\d+|\d+/g, PleaseWork);
}
You want match() not replace(), match returns an array with the matches.
Also, beware of the minus key vs dash key. They are different values on the ASCII table.

JavaScript RegExp to remove # sign from starting position

I want modify my regular expression to also remove # size but select only that word those are start with # sign.
Following is my code, View Live
JS
var a = "#abc #jat hi pat #jkl abc #cde vcd #cde ";
var s = a.match(/(?=(\s{1}?#[^\s]+)|(\s?))(#[^\s]+)(?=(\s))/g);
console.log(s);
Result
["#abc", "#jat", "#jkl", "#cde", "#cde"]
Expected Result
["abc", "jat", "jkl", "cde", "cde"]
Since JavaScript doesn't have look-behind, I don't think you can do it in a single match statement (without post-processing), because you'll want a capture group.
The post-processing is trivial with ES5's Array#map (which can be shimmed), of course:
var s = a.match(/(?=(\s{1}?#[^\s]+)|(\s?))(#[^\s]+)(?=(\s))/g).map(function(entry) {
return entry.substring(1);
});
Otherwise, you'll want to use a capture group and an exec loop.
BTW, I think the regular expression can be a lot simpler, if all you want is \s separation:
var a = "#abc #jat hi pat #jkl abc #cde vcd #cde ";
var s = a.match(/#\S+/g).map(function(entry) {
return entry.substring(1);
});
display(s.join(", "));
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" + msg + "</p>"
);
}
Unless there's some compelling reason you need to write a single regexp for this, you're much better off just doing some standard splitting and filtering.
a.split(/\s+/)
.filter(function(seg) { return seg[0]==='#'; })
.map (function(seg) { return seg.slice(1); })
It doesn't look so bad if you can use arrow functions:
a.split(/\s+/)
.filter(seg => seg[0]==='#')
.map (seg => seg.slice(1))

Regular Expressions required format

I want to validate following text using regular expressions
integer(1..any)/'fs' or 'sf'/ + or - /integer(1..any)/(h) or (m) or (d)
samples :
1) 8fs+60h
2) 10sf-30m
3) 2fs+3h
3) 15sf-20m
i tried with this
function checkRegx(str,id){
var arr = strSplit(str);
var regx_FS =/\wFS\w|\d{0,9}\d[hmd]/gi;
for (var i in arr){
var str_ = arr[i];
console.log(str_);
var is_ok = str_.match(regx_FS);
var err_pos = str_.search(regx_FS);
if(is_ok){
console.log(' ID from ok ' + id);
$('#'+id).text('Format Error');
break;
}else{
console.log(' ID from fail ' + id);
$('#'+id).text('');
}
}
}
but it is not working
please can any one help me to make this correct
This should do it:
/^[1-9]\d*(?:fs|sf)[-+][1-9]\d*[hmd]$/i
You were close, but you seem to be missing some basic regex comprehension.
First of all, the ^ and $ just make sure you're matching the entire string. Otherwise any junk before or after will count as valid.
The formation [1-9]\d* allows for any integer from 1 upwards (and any number of digits long).
(?:fs|sf) is an alternation (the ?: is to make the group non-capturing) to allow for both options.
[-+] and [hmd] are character classes allowing to match any one of the characters in there.
That final i allows the letters to be lowercase or uppercase.
I don't see how the expression you tried relates anyhow to the description you gave us. What you want is
/\d+(fs|sf)[+-]\d+[hmd]/
Since you seem to know a bit about regular expressions I won't give a step-by-step explanation :-)
If you need exclude zero from the "integer" matches, use [1-9]\d* instead. Not sure whether by "(1..any)" you meant the number of digits or the number itself.
Looking on the code, you
should not use for in enumerations on arrays
will need string start and end anchors to check whether _str exactly matches the regex (instead of only some part)
don't need the global flag on the regex
rather might use the RegExp test method than match - you don't need a result string but only whether it did match or not
are not using the err_pos variable anywhere, and it hardly will work with search
function checkRegx(str, id) {
var arr = strSplit(str);
var regx_FS = /^\d+(fs|sf)[+-]\d+[hmd]$/i;
for (var i=0; i<arr.length; i++) {
var str = arr[i];
console.log(str);
if (regx_FS.test(str) {
console.log(' ID from ok ' + id);
$('#'+id).text('Format Error');
break;
} else {
console.log(' ID from fail ' + id);
$('#'+id).text('');
}
}
}
Btw, it would be better to separate the validation (regex, array split, iteration) from the output (id, jQuery, logs) into two functions.
Try something like this:
/^\d+(?:fs|sf)[-+]\d+[hmd]$/i

Add string before a keyword - javascript

I have a forum and I would like to automatically parse some of the major links. For example, if a user makes a post like this:
You should visit StackOverflow. I found it on Wikipedia.
it would automatically parse it like this:
You should visit StackOverflow. I found it on Wikipedia.
Is this even doable using JavaScript only?
Thanks for assistance. :-)
What you want to create a clean and extensible code is create a library of word => link then you can iterate over that and do your replace inside your code.
Here is a fiddle demo doing that http://jsfiddle.net/MjV84/
$(function() {
var text = $('#foo').text(),
library = {
stackoverflow: 'http://stackoverflow.com',
wikipedia: 'http://wikipedia.com'
},
name;
for (name in library) {
text = text.replace(new RegExp(name, 'gi'), function(word) {
return ''+word+'';
});
};
$('#foo ').html(text);
});​
If you're pre-processing the text, you can use the replace function with a callback and a regular expression using an alternation:
var str = "You should visit StackOverflow. I found it on Wikipedia.";
str = str.replace(/StackOverflow|Wikipedia|etc/gi, function(m) {
var href;
switch (m.toLowerCase()) {
case "stackoverflow";
href = "http://stackoverflow.com";
break;
case "wikipedia";
href = "http://en.wikipedia.org";
break;
// ...and so on...
}
return '' + m + '';
});
YMMD points out that the above requires defining each keyword twice, which is true. When I've had to do this with a large number of keywords, I've done it by having an object with the keywords as keys, the href values as values, and built the expression dynamically:
// ==== Setup code you presumably do once
// The substitutions -- make sure the keys are in lower case
var substitutions = {
"stackoverflow": "http://stackoverflow.com",
"wikipedia": "http://en.wikipedia.org",
// ...and so on...
};
// Build the regex. Here I've used `Object.keys` which is an ES5 feature
// but you can use an ES5 shim (since it's something a shim can provide).
// Note that if your keywords include any special regular expression
// characters, you'll have to loop through the keys manually and escape
// those.
var subrex = new RegExp(Object.keys(substitutions).join("|"), "gi");
// ==== Where you're using it
var str = "You should visit StackOverflow. I found it on Wikipedia.";
str = str.replace(subrex, function(m) {
return '' + m + '';
});
Live example | source
Yes, use String.replace(regex, replaceString) to do that.
Here is an example:
var text = "You should visit StackOverflow. I found it on Wikipedia.";
var newText=text.replace(/stackoverflow/gi,
"<a href='http://www.stackoverflow.com/'>StackOverflow</a>");
The g stands for global, so it will replace all instances, and the i means case-insensitive search.
In case you are replacing common words, like "dictionary" to link to dictionary.com it would be better if you only replaced it if your users added a special tag, for example:
"You should visit StackOverflow. I found it on Wikipedia."
shouldn't be replaced with links unless it was written like this:
"You should visit &StackOverflow. I found it on Wikipedia."
Then your method would just need to add the special symbol.
Also, I would have the data in an array like this:
var linkArray = [ ["StackOverflow", "http://www.stackoverflow.com/", "Description"],
["Wikipedia", "http://wikipedia.org/", "Free encyclopedia"] ];
Then create a loop to find and replace the instances:
function addLinks(textInput) {
for (var i=0; i<linkArray.length; i++) {
textInput = addLink(textInput, linkArray[i]);
}
return textInput;
}
function addLink(textInput, link) {
var replaceString = "<a href=\"" + link[1] + "\" title=\""
+ link[2] + "\">"
+ link[0] + "</a>";
return textInput.replace(new RegExp("&"+link[0], "gi"), replaceString);
}
All the previous answers using the i modifier on the regular expression fail if the target
string contains variants of the substitution strings differing by case. This is because the
target string substring does not match the substitutions attribute name.
This version solves this by capturing each of the substitution strings and searching the arguments array for the found string.
function substitute (str) { 'use strict';
var substitutions = {
"Stack Overflow": "http://stackoverflow.com",
"Wikipedia": "http://en.wikipedia.org",
// ...and so on...
},
skeys = Object.keys (substitutions);
// build regexp which will capture each match separtely
return str.replace (new RegExp ('(' + skeys.join(")|(") + ')', "gi"), function (m0) {
// Now scan the arguments array (omitting the last two arugments which
// are the source string and match index)
for (var ai, i = arguments.length - 2; --i;) {
// The index of the argument (less 1) corresponds to the index in skeys of
// the name in the substitutions
if ((ai = arguments[i])) {
return '' + ai + '';
}
}
return m0;
});
}
var str = "You should visit stack overflow. I found it on Wikipedia.";
// check in console log that links are correctly built.
console.log (substitute (str));
document.write (substitute (str));
See the jsfiddle : http://jsfiddle.net/NmGGN/

Replicating Codeigniter's humanize() and underscore() function in Javascript

I'm trying to replicate CI's humanize() and underscore() function in Javascript.
From the CI documentation, underscore() takes multiple words separated by spaces and underscores them while humanize() takes multiple words separated by underscores and adds spaces between them. The CI implementation looks something like:
function underscore($str) {
return preg_replace('/[\s]+/', '_', strtolower(trim($str)));
}
function humanize($str) {
return ucwords(preg_replace('/[_]+/', ' ', strtolower(trim($str))));
}
My code doesn't have to replicate the behavior exactly, but for the underscore() function I'd like it to be able to deal with multiple whitespace characters, while the humanize() function can be a bit looser and assume that only one underscore will only be there to separate each word.
So far what I have is:
function underscore(string) {
string = $.trim(string).toLowerCase();
var oldString;
while(oldString !== string){
oldString = string;
string = string.replace(/\s+/, '_');
}
return string;
}
function humanize(string) {
string = $.trim(string);
var terms = string.split('_');
for(var i=0; i < terms.length; i++){
terms[i] = terms[i].charAt(0).toUpperCase() + terms[i].slice(1);
}
return terms.join(' ');
}
Which works fine, yes, but I don't really like the way I did this (It's way too long compared to the PHP. There must be a more compact version), so I'm wondering if there's a more efficient / readable method to achieve this.
You can use the g modifier to do the replacement globally as:
function underscore(string) {
string = $.trim(string).toLowerCase();
return string.replace(/\s+/g, '_');
}

Categories