How can I put names into title case in JavaScript? - javascript

I've been looking around on how to use JavaScript to set names to proper case, e.g. george mchall would become George McHall. I was able to find a write up on Codeproject on how to do this, as well as a person that intended it to do this:
function toProperCase(s){
return s.toLowerCase().replace( /\b((m)(a?c))?(\w)/g,
function($1, $2, $3, $4, $5) {
if($2){
return $3.toUpperCase()+$4+$5.toUpperCase();
}
return $1.toUpperCase();
});
}
This allows for what I'm looking for. But I need to be able to extend it further and add additional cases.
I found another page on John Gruber's site doing title case, but I'm only looking at doing names.
So, does anyone have an idea on extending it? I'm really just looking for a point in the right direction.
Edit:
Since I seem to be hitting a wall here, maybe someone has a way to do it server side. This is at least for now using ColdFusion for the server side. I've seen a C# implementation, but I'm not able to move to C# at the moment.

Combining a few answers from similar posts:
var selElem = document.getElementById("fromName");
selElem.addEventListener("change", function() {
document.getElementById("result").innerHTML = properName(selElem.value);
});
function properName(name) {
return ("" + name.replace(/[^\s\-\']+[\s\-\']*/g, function(word) {
return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();
}).replace(/\b(Van|De|Der|Da|Von)\b/g, function(nobiliaryParticle) {
return nobiliaryParticle.toLowerCase();
}).replace(/Mc(.)/g, function(match, letter3) {
return 'Mc' + letter3.toUpperCase();
}));
}
<p>
Choose a name to see it properly capitalised:
</p>
<select id="fromName">
<option>Select a name</option>
<option>EMMA HURST</option>
<option>CHRIS HINDI</option>
<option>OSCAR GRENFELL</option>
<option>JIM CASEY</option>
<option>MEOW-LUDO DISCO GAMMA MEOW-MEOW</option>
<option>PAT SHEIL</option>
<option>NOEL MCFARLANE</option>
<option>CHRIS MCLACHLAN</option>
<option>ANTHONY ALBANESE</option>
<option>DAVID VAN GOGH</option>
<option>JAMIE ELVY</option>
</select>
<p>Result: <span id="result"></span></p>

How about this:
if (str==str.toLowerCase() || str==str.toUpperCase())
str = str.toTitleCase();
Otherwise, leave it well alone!!!
Edit: You could optionally split the string to weed out people holding the shift key for too long, like SMith.

Related

Convert text to link base on char receive

I have a post that contains a content body, the text in content body need to be properly formatted.
If the content contain a special keyword #, # i want to convert it to a usefull link.
content = "These is a sample post it can contain any thing and i can mention people with #username and show hastag reference #stackoverflowQuestion";
newContent = content.split(" ");
username = [];
hashtag = [];
newContent.forEach((sub) => {
at = sub.indexOf("#");
tag = sub.indexOf("#");
if(at == 0){
trendname.push(sub)
}
if(tag == 0){
hashtag.push(sub)
}
return sub;
});
username.forEach((user) => {
user.link = user.replace(/#/, "/${user}");console.log(user.link);
return user;}); console.log(user.link);
hashtag.forEach((str) => {
str.taged= str.replace(/([a-z])([A-Z])/g, '$1 $2').toLowercase;
return str;}); console.log(str.taged);
Firstly the code above is not loging vakue outside the loop.
Secondly is there any other way to re-write these sode because it look in efficient. if there is Please specify.
Thanks
your question is a little bit complicated to understand I think... But anyways I hope the following will help you somehow.
First, you can simplify your first loop to:
let usernames = content.match(/#([^ ]*)/g)
let hashtags = content.match(/#([^ ]*)/g)
Those are regex, and they work as follow:
They begin with # or # (if you are looking for usernames or hashtags)
[^ ]* means "Everything but a white space, and multiple times (*)
So now, you can construct user objects:
let users = usernames.map(username => {
return {
username: username,
link: '/' + username.slice(1, username.length)
}
}) // --> [ { username: '#username', link: '/username' } ]
Here is the complete code I wrote:
let content = "These is a sample post it can contain any thing and i can mention people with #username and show hastag reference #stackoverflowQuestion";
let usernames = content.match(/#([^ ]*)/g)
let hashtags = content.match(/#([^ ]*)/g)
let users = usernames.map(username => {
return {
username: username,
link: '/' + username.slice(1, username.length)
}
})
console.log(users)
Something is wrong with your code. You are making a forEach on an array of strings, and then you try to set a property to that string: user.link = ....
Secondly, you are trying to log values outside of your loops, and doing so puts you out of the scope of the loop. So you can't log those variables and this is completely normal because they just don't exist anymore... Try to indent your code better, you'll see it directly.
Hope this helps, and try working a little bit on the redaction of your questions, the stack overflow community can be harsh some times

set expected result as true when find in a string partly correct protractor

Hello everyone I got following code:
it('Search for string', function () {
var MySearch = element(by.model('searchQuery'));
MySearch.sendKeys('Apple Pomace');
expect(MySearch.getAttribute('value')).toBe('Apple Pomace');
element(by.buttonText('Search')).click();
//browser.pause();
var optionTexts = element.all(by.repeater('product in products')).map(function (Options) {
return Options.getText();
});
optionTexts.then(function (array){
expect(array).toContain("Apple Pomace");
});
});
then I get as result:
[ 'Apple Pomace\nFinest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.\n0.89' ]
now I want to check if the string contains Apple Pomace
I have tried following code:
expect(array).toContain('Apple Pomace');
then I get:
Expected [ 'Apple Pomace
Finest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.
0.89' ] to contain 'Apple Pomace'. <Click to see difference>
how do I set the test to true even if the whole string doesn't match my result?
or validate the string to the first "\" ?
code
Thank you in advance
First of all element.all(by.repeater('product in products')).getText() will return array of strings.If you use toContain matcher on the array, it will check for the whole string to be present in the array.
In your case, you need to check if the entire array has any string that matches the word Apple Pomace. To achieve this, you need to transform the result array into a string and then apply toContain matcher on it.
var displayedResults = element.all(by.repeater('product in products')).getText()
.then(function(resultArray){
return resultArray.join(); // will convert the array to string.
})
expect(displayedResults).toContain("Apple Pomace");
Hope this might help you!

Using JS/jQuery to do string search/fuzzy matching?

entirely in JS, no server backend. I need to allow the user to search and then show a list of matched names. I'm using jQuery UI AutoComplete but need some JS to filter the results.
Given an Array of names:
Bob Hope
James Jones
Steve Jobs
Larry McBridge
Given a search term like Bo
How can I get just Bob Hope to return
Given a Search term like b:
How can I get all but James Jones?
Any simple JS for comparing two strings? Thanks
var names = ["Bob Hope","James Jones","Steve Jobs","Larry McBridge"]
var query = "bo"
var results = $(names)
.map(function(i,v){
if(v.toLowerCase().indexOf(query.toLowerCase())!=-1){return v}
}).get()
// results is ["Bob Hope"]
Maybe I misunderstood you (given the complexity of the above answer), but I came up with this which uses jQuery. Every time a key is pressed (when the input has focus), it searches all li elements on the page and finds whether they contain the search term.
Here is the HTML:
<ul><li>Bob Hope</li>
<li>James Jones</li>
<li>Steve Jobs</li>
<li>Larry McBridge</li></ul><br>
Search: <input id="search" length="24" />
And here is your jQuery:
$("#search").keyup(function(){
$("li").hide();
var term = $(this).val();
$("li:contains('" + term + "')").show();
});
Using Ivan's answer, but with ES6 changes:
var names = ["Bob Hope","James Jones","Steve Jobs","Larry McBridge"];
function findIn(s, list){
return list.filter((v) => v.toLowerCase().indexOf(s.toLowerCase()) != -1 );
}
findIn('bo', names);

Javascript Regular Expression to attempt to split name into Title/First Name(s)/Last Name

I want to try and detect the different parts of a person's name in Javascript, and cut them out so that I can pass them onto something else.
Names can appear in any format - for example:-
miss victoria m j laing
Miss Victoria C J Long
Bob Smith
Fred
Mr Davis
I want to try and write something simple, that'll do it's best to guess these and get them right 80% of the time or so (We have some extremely dodgy data)
I'm thinking of something along the lines of using a regex to check whether it has a prefix, then branch off to two places as to whether it has
/^(Dr|Mr|Mrs|Miss|Master|etc).? /
And then cutting the rest of it out using something like
/(\w+ )+(\w+)/
To match last name and other names. Though, I'm unsure on my greedy/ungreedy options here, and whether I can do soemthing to shortcut having all the different paths that might be available. Basically, hoping to find something simple, that does the job in a nice way.
It's also got to be written in Javascript, due to the limitations of the ETL tool I'm using.
Why not split() and just check the resulting parts:
// Split on each space character
var name = "Miss Victoria C J Long".split(" ");
// Check the first part for a title/prefix
if (/^(?:Dr|Mr|Mrs|Miss|Master|etc)\.?$/.test(name[0])) {
name.shift();
}
// Now you can access each part of the name as an array
console.log(name);
//-> Victoria,C,J,Long
Working Demo: http://jsfiddle.net/AndyE/p9ra4/
Of course, this won't work around those other issues people have mentioned in the comments, but you'd struggle on those issues even more with a single regex.
var title = '';
var first_name = '';
var last_name = '';
var has_title = false;
if (name != null)
{
var new_name = name.split(" ");
// Check the first part for a title/prefix
if (/^(?:Dr|Mr|Mrs|Miss|Master)\.?$/i.test(new_name[0]))
{
title = new_name.shift();
has_title = true;
}
if (new_name.length > 1)
{
last_name = new_name.pop();
first_name = new_name.join(" ");
}
else if(has_title)
{
last_name = new_name.pop();
}
else
{
first_name = new_name.pop();
}
}
Adapted from Accepted Answer :)

Javascript RegEx Help

I want to take strings like:
Submit Changes
Create New
Update Record
Save Item
and convert them to:
Submitting Changes
Creating New
Updating Record
Saving Item
with a function like:
var ConvertToProgressivePresent = (function(){
// cache this regex
var rProgressivePresent = /\b(?:(Submi(t))|(Creat|Sav|Updat)e)\b/i;
return function(phrase){
return phrase.replace(rProgressivePresent, "$1$2$3ing");
};
}());
This above regex works but doesn't seem like the best way to do it. I don't like the grouping here where 1-2 groups are always empty when there is a match.
Got any suggestions or improvements?
If you have specific words to replace with then you could make a word bank. Have the words and their replacement stored in an object and then loop through it.
var ConvertToProgressivePresent = (function() {
var replaceValues = {
"Submit": "Submitting",
"Create": "Creating",
"Update": "Updating",
"Save": "Saving"
}
return function(phrase) {
for (var item in replaceValues) {
phrase = phrase.replace(item, replaceValues[item]);
}
return phrase;
};
}());
Here is a JSFiddle Example
I think you should probablly use CASE statments instead. Regex isn't the most efficient way of doing things...and that is probably best that it doesn't cuz you know the old saying.
Wow, I have this problem...I know, I'll use regex...ok, now you have two problems 90)
First off, it doesn't appear to me that your regex does quite what you want anyway in that I don't see a second "t" added when changing submit to submitting.
However, I don't think I would use regex for this task at all anyway. If you are just trying to replace one word with another, and the word always comes at the beginning of the string, I might do something like:
function ReplaceIfBeginsWith(wholeString, checkFor, replaceWith)
{
if (wholeString.indexOf(checkFor + ' ') == 0)
{
return replaceWith + ' ' + wholeString.substr(checkFor.length + 1);
}
if (wholeString == checkFor)
{
return replaceWith;
}
return wholeString;
}
Then, you can call the function with each of the words you would want to replace. If you want case-insensitivity, just check against lowercase versions of all the strings.

Categories