This is an example of the input:
var input="0-test-different-0_0:11,0-test-different-0_1:54,0-test-different-1_0:19,0-test-different-1_1:8,0-test-same-2_0:20,0-test-same-2_1:20,0-test-different-3_0:19,0-test-different-3_1:16,0-test-different-4_0:18,0-test-different-4_1:17,0-test-different-5_0:20,0-test-different-5_1:11,0-test-different-6_0:20,0-test-different-6_1:12,0-test-same-7_0:20,0-test-same-7_1:16,0-test-different-8_0:17,0-test-different-8_1:11,0-test-same-9_0:19,0-test-same-9_1:17,01-trial-same-10_0:19,01-trial-same-10_1:23,02-trial-different-11_0:22,02-trial-different-11_1:10,03-trial-different-12_0:20,03-trial-different-12_1:12,04-trial-same-13_0:18,04-trial-same-13_1:14,05-trial-same-14_0:17,05-trial-same-14_1:19,06-trial-different-15_0:21,06-trial-different-15_1:10,07-trial-same-16_0:20,07-trial-same-16_1:17,08-trial-different-17_0:20,08-trial-different-17_1:8,09-trial-same-18_0:20,09-trial-same-18_1:10,10-trial-different-19_0:21,10-trial-different-19_1:10,11-trial-same-20_0:19,11-trial-same-20_1:12,12-trial-same-21_0:19,12-trial-same-21_1:16,13-trial-different-22_0:19,13-trial-different-22_1:14,14-trial-different-23_0:22,14-trial-different-23_1:13,15-trial-same-24_0:19,15-trial-same-24_1:12,16-trial-same-25_0:18,16-trial-same-25_1:10,17-trial-different-26_0:20,17-trial-different-26_1:30,18-trial-different-27_0:21,18-trial-different-27_1:20,19-trial-same-28_0:17,19-trial-same-28_1:15,20-trial-different-29_0:17,20-trial-different-29_1:12,21-trial-different-30_0:18,21-trial-different-30_1:11,22-trial-different-31_0:16,22-trial-different-31_1:13,23-trial-same-32_0:19,23-trial-same-32_1:13,24-trial-different-33_0:19,24-trial-different-33_1:11,25-trial-same-34_0:20,25-trial-same-34_1:17,26-trial-same-35_0:22,26-trial-same-35_1:20,27-trial-same-36_0:20,27-trial-same-36_1:14,28-trial-same-37_0:22,28-trial-same-37_1:11,29-trial-different-38_0:19,29-trial-different-38_1:15,30-trial-same-39_0:19,30-trial-same-39_1:14,31-trial-different-40_0:18,31-trial-different-40_1:10,32-trial-different-41_0:18,32-trial-different-41_1:12-0-test-different-0_0:8,0-test-different-0_1:54,0-test-different-1_0:21,0-test-different-1_1:11,0-test-same-2_0:24,0-test-same-2_1:20,0-test-different-3_0:13,0-test-different-3_1:18,0-test-different-4_0:20,0-test-different-4_1:20,0-test-different-5_0:19,0-test-different-5_1:10,0-test-different-6_0:18,0-test-different-6_1:13,0-test-same-7_0:16,0-test-same-7_1:16,0-test-different-8_0:15,0-test-different-8_1:10,0-test-same-9_0:22,0-test-same-9_1:15,01-trial-same-10_0:20,01-trial-same-10_1:23,02-trial-different-11_0:24,02-trial-different-11_1:14,03-trial-different-12_0:18,03-trial-different-12_1:14,04-trial-same-13_0:18,04-trial-same-13_1:12,05-trial-same-14_0:23,05-trial-same-14_1:21,06-trial-different-15_0:21,06-trial-different-15_1:12,07-trial-same-16_0:19,07-trial-same-16_1:16,08-trial-different-17_0:22,08-trial-different-17_1:8,09-trial-same-18_0:21,09-trial-same-18_1:7,10-trial-different-19_0:16,10-trial-different-19_1:10,11-trial-same-20_0:21,11-trial-same-20_1:10,12-trial-same-21_0:18,12-trial-same-21_1:20,13-trial-different-22_0:19,13-trial-different-22_1:13,14-trial-different-23_0:17,14-trial-different-23_1:9,15-trial-same-24_0:19,15-trial-same-24_1:11,16-trial-same-25_0:23,16-trial-same-25_1:11,17-trial-different-26_0:21,17-trial-different-26_1:27,18-trial-different-27_0:20,18-trial-different-27_1:22,19-trial-same-28_0:19,19-trial-same-28_1:19,20-trial-different-29_0:21,20-trial-different-29_1:10,21-trial-different-30_0:19,21-trial-different-30_1:11,22-trial-different-31_0:20,22-trial-different-31_1:10,23-trial-same-32_0:21,23-trial-same-32_1:10,24-trial-different-33_0:19,24-trial-different-33_1:14,25-trial-same-34_0:16,25-trial-same-34_1:16,26-trial-same-35_0:22,26-trial-same-35_1:22,27-trial-same-36_0:23,27-trial-same-36_1:18,28-trial-same-37_0:19,28-trial-same-37_1:12,29-trial-different-38_0:21,29-trial-different-38_1:13,30-trial-same-39_0:22,30-trial-same-39_1:13,31-trial-different-40_0:21,31-trial-different-40_1:11,32-trial-different-41_0:19,32-trial-different-41_1:11";
At string index 2015 there is a - which actually separates this string in two.
It is different from all the other dashes in that it is the ONLY one preceeded by a colon (:) and then 1 to N numbers before there is a dash.
The way I've been finding it is by using this procedure:
var searchingColon = true;
for (var i = 0; i < input.length; i++){
if ((searchingColon) && (input.charAt(i) == ':')){
searchingColon = false;
}
else if (!searchingColon){
if (input.charAt(i) == "-"){
console.log("Found at " + i);
return;
}
if (isNaN(parseInt(input.charAt(i), 10))) {
searchingColon = true;
}
}
}
However it takes a while and I thought a regular expression would be better.
So I've tried this:
regex = "/:[0-9]+-/"
var res = input.search(regex)
console.log(res)
But res is -1, which mean it hasn't found anything. What am I doing wrong?
You should remove the quotes. Regular expressions in JavaScript are enclosed by forward slashes, not quotes.
regex = /:[0-9]+-/;
var res = input.search(regex)
console.log(res)
However, you can create a regex surround by quotes if you use the Regex constructor.
var regex2 = new RegExp(':[0-9]+-');
I usually prefer the first method, because you have to escape the \ and use \\ if you use the string variation.
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.
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.
I have an infix expression: ((attribute1*attribute2)/attribute3+attribute4)
It may vary according to the user input. I want to check whether the expression is valid.
Valid example: ((attribute1*attribute2)/attribute3+attribute4)
Invalid example: (attrribute1*attribute2+*(attribute3)
The second one has no closing parenthesis; also the * operator is not needed. How can I perform this sort of validation in javascript?
Now this is my regex:
/ *\+? *\-? *[a-zA-Z0-9]+ *( *[\+\-\*\/\=\<\>\!\&\|\%] *\+? *\-? *[a-zA-Z0-9]+ *)*/
I need a regex for comparison operators like <= , >= , != , == etc. How can I implement this?
You could try something like this:
function validateInfix(infix) {
var balance = 0;
// remove white spaces to simplify regex
infix = infix.replace(/\s/g, '');
// if it has empty parenthesis then is not valid
if (/\(\)/.test(infix)) {
return false;
}
// valid values: integers and identifiers
var value = '(\\d+|[a-zA-Z_]\\w*)';
// the unary '+' and '-'
var unaryOper = '[\\+\\-]?';
// the arithmetic operators
var arithOper = '[\\+\\-\\*\\/]';
// the comparison operators
var compOper = '(\\<\\=?|\\>\\=?|\\=\\=|\\!\\=)';
// if it has more than one comparison operator then is not valid
if (infix.match(new RegExp(compOper, 'g')).length > 1) {
return false;
}
// the combined final regex: /[\+\-]?(\d+|[a-zA-Z_]\w*)(([\+\-\*\/]|(\<\=?|\>\=?|\=\=|\!\=))[\+\-]?(\d+|[a-zA-Z_]\w*))*/
var regex = new RegExp(unaryOper + value + '((' + arithOper + '|' + compOper + ')' + unaryOper + value + ')*');
// validate parenthesis balance
for (var i = 0; i < infix.length; i++) {
if (infix[i] == '(') {
balance++;
}
else if (infix[i] == ')') {
balance--;
}
if (balance < 0) {
return false;
}
}
if (balance > 0) {
return false;
}
// remove all the parenthesis
infix = infix.replace(/[\(\)]/g, '');
return regex.test(infix);
}
The idea is to check first the parenthesis balance, then remove them all given that we only want to validate and not evaluate, and then match the remaining expression to a regex (which may not be perfect, I'm not a regex expert). And... just in case: infix argument must be a string.
Edit
I noticed a couple of details and changed the code a bit:
Added the operators you needed the regex to match too.
Removed white spaces to get rid of regex junk.
Checked if the expression had empty parenthesis.
Checked if the expression had more than one comparison operators.
Changed this \+?\-? by this [\+\-]?.
Changed string match method by regex test method where possible.
Changed this [a-zA-Z0-9] by this (\d+|[a-zA-Z_]\w*) since the first one matches wrong identifiers like 53abc.
For better understanding and clarity, extracted pieces of regex into separate variables and built the final one from these.
Hope this is ok for you now :)
Currently I have an editable div and I want to add very basic syntax highlighting. Essentially I want text between * to turn a different color and text in quotes to turn a different color. For example:
input: "hello" *world*
output: <span class='a'>"hello"</span> <span class='b'>*world*</span>
I'm using Rangy.js library to save and restore the caret position so there's no issues there. However I'm really struggling to turn the input into the output. The big problem I have is ignoring any " and * that are already highlighted.
If anyone could point me in the direction of a basic algorithm or regular expression or something it would be much appreciated.
function highlight(text) {
var result = [];
for (var i = 0; i < text.length; i++) {
if (text[i] === '"') {
var stop = text.indexOf('"', i + 1);
result.push('<span class="a">');
result.push(text.substring(i, stop+1));
result.push('</span>');
i = stop;
}
else if (text[i] === '*') {
var stop = text.indexOf('*', i + 1);
result.push('<span class="b">');
result.push(text.substring(i, stop+1));
result.push('</span>');
i = stop;
}
else if (text[i] === '<') {
// Skip simple HTML tags.
var stop = text.indexOf('>', i + 1);
result.push(text.substring(i, stop+1));
i = stop;
}
else {
result.push(text.substring(i,i+1));
}
}
return result.join('');
}
Example:
>>> highlight('foo *bar"baz"qux* "foobar" qux')
"foo <span class="b">*bar"baz"qux*</span> <span class="a">"foobar"</span> qux"
Or with regular expressions:
function highlight2(text) {
return text.replace(/([*"]).*?\1|<[^<>]*>/g, function (match, ch) {
// 'match' contains the whole match
// 'ch' contains the first capture-group
if (ch === '"') {
return '<span class="a">' + match + '</span>';
}
else if (ch === '*') {
return '<span class="b">' + match + '</span>';
}
else {
return match;
}
});
}
The regular expression ([*"]).*?\1 contains the following:
[*"] matches * or ". (They don't need to be escaped inside [ ]).
( ) captures the matched string into capture-group 1.
.*? matches anything up until the first...
\1 matches the same string as was captured into capture-group 1.
| is "Or". It tries to match the left side, and if that fails, it tries to match the right side.
<[^<>]*> matches simple html-tags. It will not be able to handle attributes with literal < or > in them: <a href="info.php?tag=<i>"> (that is bad HTML anyway, but some browsers will accept it.)
In the case when it matches an HTML tag, the ch parameter will be undefined, and the else-branch will be picked.
If you want to add more characters, just put them inside the [ ], and add an if-statement to handle them. You can use any character except -, \ and ] without escaping them. To add those characters, you need to put another \ in front of them.
Your basic algorithm is
function highlight(myInput) {
// Split the string into tokens.
// "[^"]*" matches a minimal run surrounded by quotes
// \*[^*]*\* matches a minimal run surrounded by asterisks
// ["*][^"*]* matches an unmatched quote or asterisk and the tail of the string
// [^"*]+ matches a maximal un-styled run
var tokens = myInput.match(/"[^"]*"|\*[^*]*\*|["*][^"*]*$|[^"*]+/g);
// Walk over the list of tokens and turn them into styled HTML
var htmlOut = [];
for (var i = 0, n = tokens.length; i < n; ++i) {
var token = tokens[i];
// Choose a style.
var className =
token.charAt(0) == '"' ? "a" : token.charAt(0) == '*' ? "b" : null;
// Surround in a span if we have a style.
if (className) { htmlOut.push("<span class='", className, "'>"); }
// HTML escape the token content.
htmlOut.push(token.replace(/&/g, "&").replace(/</g, "<"));
if (className) { htmlOut.push("</span>"); }
}
// Join the output tokens.
return htmlOut.join('');
}
alert(highlight('"hello" *world*'));