watkins577
672 posts
|
I need to check a string for a pig latin translator Im making, and if theres punctuation It kinda messes things up… e.g. Hey! will become ey!hay when it should be eyhay!
Any help will be appreciated as long as it is constructive, thanks.
-Watkins
|
|
|
UnknownGuardian
6219 posts
|
Check out RegExp. That might be a bit useful.
|
|
|
Jabor
11382 posts
|
“Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems."
If you don’t know what you’re doing you can get into a lot of trouble with regular expressions. On the other hand, if you do know what you’re doing, they can be really useful. For example:
function pigLatin(str) {
var pattern = /^([a-zA-Z]+)(.*)$/;
var result = pattern.exec(str);
var piglatin = piggify(result[1]) + result[2];
return piglatin;
}
Will “piggify” the part of the string that consists of letters, and leave the nonletter part unchanged.
Before using the above code, you should read up on regular expression syntax and satisfy yourself that you understand how that regular expression works. At the very least, you should be able to state in words what it matches.
|
|
|
Wordblind
1053 posts
|
Also, look at the functions in the String class. The replace function is especially flexible, as it can take a pattern or a function as the second argument.
function pigLatin(str:String):String {
return str.replace(/[a-z]+/ig, pigify);
}
function pigify():String {
return (arguments[0] as String).replace(/([^aeiouy]*)(.*)/ig, "%2%1ay");
}
|
|
|
Jabor
11382 posts
|
That is pretty neat.
In fact, that’s an all-around more elegant solution to the problem (what with handling the string in its entirety instead of having to tokenize it first).
Ignore my code and use Wordblind’s once you can explain what each regex in it matches.
|
|
|
watkins577
672 posts
|
Im never used regexp before So tbh its all gobbledygook to me. /[a-z] Im guessing is to check if its part of the alphabet… so Im gessing /ig is numeric. I have no idea about the pigify part lol.
BTW this is my code atm:
function trans(fromto:String, list:String):String {
var firstlet:String = "";
var newstr:String = "";
list = list.toLowerCase();
var listarr:Array = [];
listarr = list.split(" ");
var wordarr:Array = [];
var word:String = "";
var finalword = "";
var failed = false;
if (listarr == []) {
fromto == "cancel";
}
if (fromto == "etp") {
for (var i = 0; i < listarr.length; i++) {
word = listarr[i];
firstlet = word.charAt(0);
newstr = word.slice(1, word.length);
newstr = newstr + firstlet + "ay";
wordarr[i] = newstr;
}
} else if (fromto == "pte") {
for (var j = 0; j < listarr.length; j++) {
word = listarr[j];
if (word.slice(word.length-2, word.length) == "ay") {
firstlet = word.charAt(word.length-3);
newstr = word.slice(0, word.length-3);
newstr = firstlet + newstr;
wordarr[j] = newstr;
} else {
wordarr[j] = word;
}
}
}
for (var k = 0; k < wordarr.length; k ++) {
finalword = finalword + wordarr[k];
if (k != wordarr.length - 1) {
finalword = finalword + " ";
}
}
return finalword;
}
It doesnt really work well with regexp unless it is adapted.
|
|
|
watkins577
672 posts
|
Ok I sorted it out Thanks for all the help (Id still like to know what those regexp things are though)
|
|
|
Jabor
11382 posts
|
|
|
|
Wordblind
1053 posts
|
No…really…go read a tutorial on regular expressions. It is, literally, the best investment of an hour any aspiring programmer can make. (There are cooler things, but they take longer than an hour to learn.)
I’ll start you out:
* = zero or more
+ = one or more
. = any character
[ab] = one character, a or b
[^ab] = one character, neither a nor b
/cat/ = "cat"
/cat/i = case insensitive - "Cat", "cAt", "CAt", etc.
/cat/g = global - each and every "cat"
Also, see if you can guess why I prefer
finalword = wordarr.join(" ");
to
for (var k = 0; k < wordarr.length; k ++) {
finalword = finalword + wordarr[k];
if (k != wordarr.length - 1) {
finalword = finalword + " ";
}
}
Hint: It has nothing to do with length or clarity.
|
|
|
Jaywalker2
692 posts
|
Umm, I’m going to accept Wordblind’s challenge in an attempt to learn…do not mock me when I fail to get the right answer.
for loops are inefficient, and keep checking the same thing over and over?
Is it along those lines?
Eh, I tried.
EDIT: Thanks, Jabor. That’s awesome. Cos knowledge is power, etc.
|
|
|
Jabor
11382 posts
|
The reason is something to do with “doing the same thing over and over”, but not to do with checking anything.
When you concatenate two strings with the ‘+’ operator, both strings are copied to a new bit of memory, one after the other.
If you use ‘+’ in a loop, first you copy the first string somewhere else, then you copy the second string just after it.
Then you copy both those strings to a completely new bit of memory, and copy the third string to a spot just after it.
Then you copy all of those strings to a completely new bit of memory, and so on.
So you end up copying the first strings over and over, for absolutely no reason at all.
join is much more efficient, because it allocates one big chunk of memory and copies each string once and once only.
|