Somebody can help me with this function on javascript?
i did this function above on javascript, but when i try to use on this string: Item 1 – 1 X 500 OS 129062.
MATERIAL DE NOSSA PROPRIEDADE QUE SEGUE P/ ANALISE E TESTE, SEM DÉBITO
(AMOSTRA GRÁTIS).
I get a error: Unclosed group near index 1
Plz, help me
function retiraAcentos(texto) {
var caracEspec = '.áàãâäéèêëíìîïóòõôöúùûüçñÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇÑ/';
var caracComum = '.aaaaaeeeeiiiiooooouuuucnAAAAAEEEEIIIIOOOOOUUUUCN.';
var textoResultado = '';
for (i = 0; i < texto.length; i++) {
var letra = texto.substr(i, 1);
if ((letra == "*") || (letra == "?") || (letra == "\n") || (letra == '+')) {
continue;
}
var posLetra = caracEspec.search(letra);
if (posLetra >= 0) {
textoResultado += caracComum.substr(posLetra, 1);
} else {
textoResultado += letra;
}
}
return textoResultado;
}
The search function expects a regular expression. Try using indexOf instead:
var posLetra = caracEspec.indexOf(letra);
I made some research using jsfiddle.
It turns out that if a text contains a parenthesis (opening or closing),
then such a parenthesis at some point becomes the argument of search
function and it raises unterminated parenthetical error.
Apparently this function uses regex internally and a single parenthesis
is not any valid regex.
Use indexOf instead of search.
Another correction: Remove dot char from the beginning of caracEspec
and caracComum.
If you used search then the dot (treated as regex) matched any char,
in this case the first char from caracEspec, giving posLetra = 0.
This resulted in taking the 1st char from caracComum (fortunately, also a dot).
Now these combinations are not needed.
Related
been working on a school problem, and haven't been able to figure it out. Any help is appreciated!
Write a function named countBrackets that accepts a string
and returns the count of square bracket and curly bracket
characters in the string. That is, it should count occurrences of
these four characters “{ } [ ]”. Use function expression syntax.
var countBrackets = function(s){
let sum = 0
for(let i = ""; i == s ; i++ )
if(i ==="{}[]"){
sum+=i
}
return sum}
console.log(countBrackets("[123],{456},[{}]")) //8
console.log(countBrackets("Test string")) // 0
I'm a little confused on how I'm supposed to get it to count a string I guess.
You can use a global regex (regular expression) matching for this. The regex is between / / followed by the g flag to make it global (otherwise it only returns the first result it finds and stops).
Within the regex, | is the OR operator, so you match for /{|}|[|]/
Since [ and ] have special meaning in regular expressions you need to escape those using a \ so your total regex becomes /{|}|\[|\]/g.
This returns an array of matches, I called the function findBrackets.
To get the number of brackets, the function countBrackets just returns the .length of that array.
const findBrackets = str => str.match(/{|}|\[|\]/g);
const countBrackets = str => findBrackets(str) ? findBrackets(str).length : 0;
console.log(findBrackets('qw[e}rt[y]ui{}o{p'));
console.log(countBrackets('qw[e}rt[y]ui{}o{p'));
console.log(countBrackets('no brackets here'));
Edit: seeing the code you posted, you decided to use a for-loop to loop over your string, which is a totally valid solution.
Note that in my above example
const findBrackets = str => str.match(/{|}|\[|\]/g);
Is basically the same but a newer way of writing functions (with a few nuances)
I could have written:
var findBrackets = function(str) {
return str.match(/{|}|\[|\]/g);
}
instead which would be almost the same.
If you want to loop over a string, you can access a letter in the string by using square bracket notation, so for example
const testString = 'hello';
console.log(testString[1]);
Would output the letter 'e'.
So to use this in a function:
const countBrackets = (str) => {
let counter = 0;
for (let i = 0; i < str.length; i++) {
if (str[i] === '[' || str[i] === ']' || str[i] === '{' || str[i] === '}') {
counter++;
}
}
return counter;
}
console.log(countBrackets('qw[e}rt[y]ui{}o{p'));
Here you loop over the string from 0 to < length of the string and check every letter of it, by seeing if str[i] is {, }, [ or ], and if it is you increment a counter. After that's done you return the final count.
I have this string:
var str = "? this is a ? test ?";
Now I want to get this:
var newstr = "this is a ? test";
As you see I want to remove just those ? surrounding (in the beginning and end) that string (not in the middle of string). How can do that using JavaScript?
Here is what I have tried:
var str = "? this is a ? test ?";
var result = str.trim("?");
document.write(result);
So, as you see it doesn't work. Actually I'm a PHP developer and trim() works well in PHP. Now I want to know if I can use trim() to do that in JS.
It should be noted I can do that using regex, but to be honest I hate regex for this kind of jobs. Anyway is there any better solution?
Edit: As this mentioned in the comment, I need to remove both ? and whitespaces which are around the string.
Search for character mask and return the rest without.
This proposal the use of the bitwise not ~ operator for checking.
~ is a bitwise not operator. It is perfect for use with indexOf(), because indexOf returns if found the index 0 ... n and if not -1:
value ~value boolean
-1 => 0 => false
0 => -1 => true
1 => -2 => true
2 => -3 => true
and so on
function trim(s, mask) {
while (~mask.indexOf(s[0])) {
s = s.slice(1);
}
while (~mask.indexOf(s[s.length - 1])) {
s = s.slice(0, -1);
}
return s;
}
console.log(trim('??? this is a ? test ?', '? '));
console.log(trim('abc this is a ? test abc', 'cba '));
Simply use:
let text = '?? something ? really ??'
text = text.replace(/^([?]*)/g, '')
text = text.replace(/([?]*)$/g, '')
console.log(text)
A possible solution would be to use recursive functions to remove the unwanted leading and trailing characters. This doesn't use regular expressions.
function ltrim(char, str) {
if (str.slice(0, char.length) === char) {
return ltrim(char, str.slice(char.length));
} else {
return str;
}
}
function rtrim(char, str) {
if (str.slice(str.length - char.length) === char) {
return rtrim(char, str.slice(0, 0 - char.length));
} else {
return str;
}
}
Of course this is only one of many possible solutions. The function trim would use both ltrim and rtrim.
The reason that char is the first argument and the string that needs to be cleaned the second, is to make it easier to change this into a functional programming style function, like so (ES 2015):
function ltrim(char) {
(str) => {
<body of function>
}
}
// No need to specify str here
function ltrimSpaces = ltrim(' ');
Here is one way to do it which checks for index-out-of-bounds and makes only a single call to substring:
String.prototype.trimChars = function(chars) {
var l = 0;
var r = this.length-1;
while(chars.indexOf(this[l]) >= 0 && l < r) l++;
while(chars.indexOf(this[r]) >= 0 && r >= l) r--;
return this.substring(l, r+1);
};
Example:
var str = "? this is a ? test ?";
str.trimChars(" ?"); // "this is a ? test"
No regex:
uberTrim = s => s.length >= 2 && (s[0] === s[s.length - 1])?
s.slice(1, -1).trim()
: s;
Step-by-step explanation:
Check if the string is at least 2 characters long and if it is surrounded by a specific character;
If it is, then first slice it to remove the surrounding characters then trim it to remove whitespaces;
If not just return it.
In case you're weirded out by that syntax, it's an Arrow Function and a ternary operator.
The parenthesis are superfluous in the ternary by the way.
Example use:
uberTrim(''); // ''
uberTrim(' Plop! '); //'Plop!'
uberTrim('! ...What is Plop?!'); //'...What is Plop?'
Simple approach using Array.indexOf, Array.lastIndexOf and Array.slice functions:
Update: (note: the author has requested to trim the surrounding chars)
function trimChars(str, char){
var str = str.trim();
var checkCharCount = function(side) {
var inner_str = (side == "left")? str : str.split("").reverse().join(""),
count = 0;
for (var i = 0, len = inner_str.length; i < len; i++) {
if (inner_str[i] !== char) {
break;
}
count++;
}
return (side == "left")? count : (-count - 1);
};
if (typeof char === "string"
&& str.indexOf(char) === 0
&& str.lastIndexOf(char, -1) === 0) {
str = str.slice(checkCharCount("left"), checkCharCount("right")).trim();
}
return str;
}
var str = "???? this is a ? test ??????";
console.log(trimChars(str, "?")); // "this is a ? test"
to keep this question up to date using an ES6 approach:
I liked the bitwise method but when readability is a concern too then here's another approach.
function trimByChar(string, character) {
const first = [...string].findIndex(char => char !== character);
const last = [...string].reverse().findIndex(char => char !== character);
return string.substring(first, string.length - last);
}
Using regex
'? this is a ? test ?'.replace(/^[? ]*(.*?)[? ]*$/g, '$1')
You may hate regex but after finding a solution you will feel cool :)
Javascript's trim method only remove whitespaces, and takes no parameters. For a custom trim, you will have to make your own function. Regex would make a quick solution for it, and you can find an implementation of a custom trim on w3schools in case you don't want the trouble of going through the regex creation process. (you'd just have to adjust it to filter ? instead of whitespace
This in one line of code which returns your desire output:
"? this is a ? test ?".slice(1).slice(0,-1).trim();
I'm new to JavaScript and not sure why my code isn't working. I'm trying to return true if there are an equal amount of x's and o's, and return false if there are not. My code works for all inputs except "x" and "o". Any help is appreciated!
My code:
function ExOh(str) {
var x = str.match(/[^x$]/gi);
var o = str.match(/[^o$]/gi);
if (x.length == o.length) {
return true;
}
else {
return false;
}
}
Your regexps allow any characters other than x/y and $. You must have meant /x/gi and /o/gi.
function ExOh(str) {
var x = str.match(/x/gi) || "";
var o = str.match(/o/gi) || "";
if (x.length === o.length) {
return true;
}
else {
return false;
}
}
alert(ExOh("zzz"));
alert(ExOh("oozzzxx"));
Note that negated character classes like [^x] match all characters other than those inside the square brackets. $ inside them is treated as a literal dollar sign.
Typing a caret after the opening square bracket negates the character class. The result is that the character class matches any character that is not in the character class. Unlike the dot, negated character classes also match (invisible) line break characters. If you don't want a negated character class to match line breaks, you need to include the line break characters in the class. [^0-9\r\n] matches any character that is not a digit or a line break.
You need to set the value to something other than null if the str.match doesn't actually match something. You can't call length on null. Use the or operator to set the value to an empty string in your variable declaration.
function ExOh(str) {
var x = str.match(/[^x$]/gi) || '';
var o = str.match(/[^o$]/gi) || '';
if (x.length == o.length) {
return true;
}
else {
return false;
}
}
I hope this helps
Here's a solution for checking that the number of two characters is the same.
// How many 'x' characters occur in a string?
function numberOf(str, x) {
var matches = str.match(new RegExp(x, 'g'));
return matches ? matches.length : 0;
}
// Create a function to check if the number of x's and o's in
// a string are the same.
function same(x, o) {
return function(str) {
return numberOf(str, x) === numberOf(str, o);
};
}
var isSame = same('x', 'o');
isSame('xxooabc');
Remove ^ and $ from your regex , [^o$] match a single character not o or $. You just need to use /x/ and /o/ and flags ig, i for ignoring case and g for global match.
Typing a caret after the opening square bracket negates the character class. The result is that the character class matches any character that is not in the character class. Unlike the dot, negated character classes also match (invisible) line break characters. If you don't want a negated character class to match line breaks, you need to include the line break characters in the class. [^0-9\r\n] matches any character that is not a digit or a line break. ( Taken from http://www.regular-expressions.info/charclass.html )
Update : Add (!x && !o) and x && o in condition for avoiing error when zero matches are there. (!x && !o) for when both are not present.x && o will help only to check the condition x.length == o.length when both x and o are defined.
var div = document.getElementById('res');
function ExOh(str) {
var x = str.match(/x/gi);
var o = str.match(/o/gi);
if ((!x&&!o) || x && o && x.length == o.length) {
res.innerHTML = 'Same';
return true;
} else {
res.innerHTML = 'Not Same';
return false;
}
}
<input type=text oninput="ExOh(this.value)">
<div id=res></div>
I have textbox and user write a formula and I get the text from textbox to split the parentheses .By the way I'm not trying to calculate formula I try to just get strings .I'm trying to get strings from nested parentheses Here is my code:
var txt = "((a-b)/month)/(c+d)";
var reg = /^\((.+)\)$/;
var newTxt = txt.split('(');
for (var i = 1; i < newTxt.length; i++) {
var value = newTxt[i].split(')')[0];
if (value == "") {
value = txt.match(reg)[1];
}
console.log(value);
}
And my output is
(a-b)/month)/(c+d
a-b
c+d
But I'm trying to get string between parentheses like
(a-b)/month
a-b
c+d
This is another way
var a = [], r = [];
var txt = "(((a-b)+(f-g))/month)/(c+d)";
for(var i=0; i < txt.length; i++){
if(txt.charAt(i) == '('){
a.push(i);
}
if(txt.charAt(i) == ')'){
r.push(txt.substring(a.pop()+1,i));
}
}
alert(r);
This will capture the text in the outer parentheses, including the parentheses themselves:
(\((?>[^()]+|(?1))*\))
Output:
((a-b)/month)
(c+d)
Explanation:
( start first capturing group
\( opening parenthesis
(?> look behind to check that...
[^()]+ ... there are no parentheses ...
| ... or that...
(?1) ... there is a nested group that has already been captured by this expression (recursion)
\) closing parenthesis
) end of capturing group
Ah. Sorry. Your question is about JavaScript and JavaScript doesn't support look-behind.
Suppose I have (in a javascript regular expression)
((((A)B)C)D)
Of course that really reads
ABCD
Is there an algorithm to eliminate unnecessary parentheses in a string like that?
This function will remove all groups that is not followed by a quantifier, and is not a look-around. It assumes ECMAScript flavor regex, and that capture-groups (( ... )) are unimportant.
function removeUnnecessaryParenthesis(s) {
// Tokenize the pattern
var pieces = s.split(/(\\.|\[(?:\\.|[^\]\\])+]|\((?:\?[:!=])?|\)(?:[*?+]\??|\{\d+,?\d*}\??)?)/g);
var stack = [];
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].substr(0,1) == "(") {
// Opening parenthesis
stack.push(i);
} else if (pieces[i].substr(0,1) == ")") {
// Closing parenthesis
if (stack.length == 0) {
// Unbalanced; Just skip the next one.
continue;
}
var j = stack.pop();
if ((pieces[j] == "(" || pieces[j] == "(?:") && pieces[i] == ")") {
// If it is a capturing group, or a non-capturing group, and is
// not followed by a quantifier;
// Clear both the opening and closing pieces.
pieces[i] = "";
pieces[j] = "";
}
}
}
return pieces.join("");
}
Examples:
removeUnnecessaryParenthesis("((((A)B)C)D)") --> "ABCD"
removeUnnecessaryParenthesis("((((A)?B)C)D)") --> "(A)?BCD"
removeUnnecessaryParenthesis("((((A)B)?C)D)") --> "(AB)?CD"
It does not try to determine if the parenthesis contains only a single token ((A)?). That would require a longer tokenizing pattern.
1) Use a parser that understands parenthesis
2) Use a Perl recursive regex that can match parenthesis (discouraged in this case IMHO) I don't think Boost regex's support the type of recursion needed.
3) Perhaps they are needed? Leave them alone.