Validate range of decimal numbers in javascript using regex - regex

I have a condition to validate a number. My requirement is accept only following numbers.
0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5
I tried with this regex but it returns false for decimal numbers.
/^[0|0.5|1|1.5|2|2.5|3|3.5|4|4.5|5]$/
The system that I am working is an existing system and I must use regular expression. No other option available for me.
Can anyone help me?

Your expression is almost correct:
/^(0|0\.5|1|1\.5|2|2\.5|3|3\.5|4|4\.5|5)$/
You need to use round brackets instead of square brackets and escape the dots. Round brackets indicate groups while square brackets define a group of single characters which may be matched. A shorter variant is this:
/^([0-4](\.5)?|5)$/
This will match any digit from 0 to 4, optionally followed by .5, or the single digit 5.

You may try the below regex.
^(?:[0-4](?:\.5)?|5)$
[0-4] will match range of digits from 0 to 4.
(?:\.5)? optional .5
DEMO

Instead of using regexes, you should really see if you can use a function.
This would be your best option, then:
function check(num) {
var floored = Math.floor(num);
return (num === floored || num - 0.5 === floored) && num >= 0 && num <=5;
}
alert(1 + ' ' + check(1) + '\n' +
5 + ' ' + check(5) + '\n' +
6 + ' ' + check(6) + '\n' +
1.5 + ' ' + check(1.5) + '\n' +
4.5 + ' ' + check(4.5) + '\n' +
5.5 + ' ' + check(5.5) + '\n' +
5.51 + ' ' + check(5.51) + '\n' +
-1.5 + ' ' + check(-1.5) + '\n' +
-0.5 + ' ' + check(-0.5))

Related

Google Script - get a text with an apostrophe in a cell (Spreadsheet) and search for it in a body of Google Doc

I did a script (container-bound script) in my Spreadsheet in which I have 4 columns: (1) text before, (2) text after, (3) text to insert between, and (4) a URL of a Google Doc with the text in which I want to replace with the right value (between).
My method replace is not working when I have an apostrophe (') I didn't tried for other characters(/," so I don't know). How to solve this?
This is my code:
var COLUMN_URL =....
var URL = ...;
// loop for n
Logger.log(' URL ' + URL);
var body = DocumentApp.openByUrl(URL).getBody();
body.replaceText(
sheet.getRange(n + 1, 2).getDisplayValue() + ".*" + sheet.getRange(n + 1, 3).getDisplayValue(),
sheet.getRange(n + 1, 2).getDisplayValue() + sheet.getRange(n + 1, 4).getDisplayValue() +
sheet.getRange(n + 1, 3).getDisplayValue()
);
Edit : I've tested with several symbols when I don't use the apostrophes,quotes, * and ? it works i will test with other symbols but for now the ! & . and numbers placed in the cells (before and after) are working
With \, ( and ) I get a message invalid regular expression pattern I love .*McDonald)s
Try \Q...\E¹
var textBfr = sheet.getRange(n + 1, 2).getDisplayValue(),
textAr = sheet.getRange(n + 1, 3).getDisplayValue(),
textInsert = sheet.getRange(n + 1, 4).getDisplayValue();
body.replaceText( "\\Q"+textBfr+"\\E"+ ".*?" +"\\Q"+textAr+"\\E", textBfr+textInsert+textAr);

Regex Queries for Lines

I am trying to figure out a couple regular expressions for the below cases:
Lines with a length divisible by n, but not by m for integers n and m
Lines that do not contain a certain number n of a given character,
but may contain more or less
I am a newcomer and would appreciate any clarification on these.
I've used JavaScript for my examples.
For the first one the key is to note that 'multiples' are just repeats. So using /(...)+/ will match 3 characters and then repeat that match as many times as it can. Each matching group doesn't need to be the same set of 3 characters but they do need to be consecutive. Suitable anchoring using ^ and $ ensures you're checking the exact string length and ?: can be used to negate.
e.g. Multiple of 5 but not 3:
/^(?!(.{3})+$)(.{5})+$/gm
Note that JavaScript uses / to mark the beginning and end of the expression and gm are modifiers to perform global, multiline matches. I wasn't clear what you meant by matching 'lines' so I've assumed the string itself contains newline characters that must be taken into consideration. If you had, say, and array of lines and could check each one individually then things get slightly easier, or a lot easier in the case of your second question.
Demo for the first question:
var chars = '12345678901234567890',
str = '';
for (var i = 1 ; i <= chars.length ; ++i) {
str += chars.slice(0, i) + '\n';
}
console.log('Full text is:');
console.log(str);
console.log('Lines with length that is a multiple of 2 but not 3:');
console.log(lineLength(str, 2, 3));
console.log('Lines with length that is a multiple of 3 but not 2:');
console.log(lineLength(str, 3, 2));
console.log('Lines with length that is a multiple of 5 but not 3:');
console.log(lineLength(str, 5, 3));
function lineLength(str, multiple, notMultiple) {
return str.match(new RegExp('^(?!(.{' + notMultiple + '})+$)(.{' + multiple + '})+$', 'gm'));
}
For the second question I couldn't come up with a nice way to do it. This horror show is what I ended up with. It wasn't too bad to match n occurrences of a particular character in a line but matching 'not n' proved difficult. I ended up matching {0,n-1} or {n+1,} but the whole thing doesn't feel so great to me. I suspect there's a cleverer way to do it that I'm currently not seeing.
var str = 'a\naa\naaa\naaaa\nab\nabab\nababab\nabababab\nba\nbab\nbaba\nbbabbabb';
console.log('Full string:');
console.log(str);
console.log('Lines with 1 occurrence of a:');
console.log(mOccurrences(str, 'a', 1));
console.log('Lines with 2 occurrences of a:');
console.log(mOccurrences(str, 'a', 2));
console.log('Lines with 3 occurrences of a:');
console.log(mOccurrences(str, 'a', 3));
console.log('Lines with not 1 occurrence of a:');
console.log(notMOccurrences(str, 'a', 1));
console.log('Lines with not 2 occurrences of a:');
console.log(notMOccurrences(str, 'a', 2));
console.log('Lines with not 3 occurrences of a:');
console.log(notMOccurrences(str, 'a', 3));
function mOccurrences(str, character, m) {
return str.match(new RegExp('^[^' + character + '\n]*(' + character + '[^' + character + '\n]*){' + m + '}[^' + character + '\n]*$', 'gm'));
}
function notMOccurrences(str, character, m) {
return str.match(new RegExp('^([^' + character + '\n]*(' + character + '[^' + character + '\n]*){0,' + (m - 1) + '}[^' + character + '\n]*|[^' + character + '\n]*(' + character + '[^' + character + '\n]*){' + (m + 1) + ',}[^' + character + '\n]*)$', 'gm'));
}
The key to how that works is that it tries to find n occurrences of a separated by sequences of [^a], with \n thrown in to stop it walking onto the next line.
In a real world scenario I would probably do the splitting into lines first as that makes things much easier. Counting the number of occurrences of a particular character is then just:
str.replace(/[^a]/g, '').length;
// Could use this instead but note in JS it'd fail if length is 0
str.match(/a/g, '').length;
Again, this assumes a JavaScript environment. If you were using regexes in an environment where you could literally only pass in the regex as an argument then it's back to my earlier horror show.

Need help to make a RegExp filter to replace redundant Parentheses

For the past few days (weeks, months, years maybe if you count my on-again off-again search and attempts) I've been trying to make or find a RegEx filter to help me remove all redundant parentheses found in my code.
A worst case scenario of what the regex filter will have to deal with is attached. As is a best case scenario
return ((((((((((((((((((((((((((getHumanReadableLine("avHardwareDisable") + getHumanReadableLine("hasAccessibility")) + getHumanReadableLine("hasAudio")) + getHumanReadableLine("hasAudioEncoder")) + getHumanReadableLine("hasEmbeddedVideo")) + getHumanReadableLine("hasIME")) + getHumanReadableLine("hasMP3")) + getHumanReadableLine("hasPrinting")) + getHumanReadableLine("hasScreenBroadcast")) + getHumanReadableLine("hasScreenPlayback")) + getHumanReadableLine("hasStreamingAudio")) + getHumanReadableLine("hasStreamingVideo")) + getHumanReadableLine("hasTLS")) + getHumanReadableLine("hasVideoEncoder")) + getHumanReadableLine("isDebugger")) + getHumanReadableLine("language")) + getHumanReadableLine("localFileReadDisable")) + getHumanReadableLine("manufacturer")) + getHumanReadableLine("os")) + getHumanReadableLine("pixelAspectRatio")) + getHumanReadableLine("playerType")) + getHumanReadableLine("screenColor")) + getHumanReadableLine("screenDPI")) + getHumanReadableLine("screenResolutionX")) + getHumanReadableLine("screenResolutionY")) + getHumanReadableLine("version")));
return ((((name + ": ") + Capabilities[name]) + "\n"));
As you can see there's... a few... redundant parentheses in my code. Been working actively with these for a very long time but have always tried to clean up what I come across and been trying to find a faster way to do it.
So one example of how the "clean" code would look, I'm hoping at least!
return (name + ": " + Capabilities[name] + "\n");
return name + ": " + Capabilities[name] + "\n";
Either one is acceptable to be completely honest as long as the code itself doesn't mock up and change how it works.
I greatly appreciate any answers anyone can give me. Please don't Mock what I do or am trying to achieve. I haven't worked much with regex or similar things before...
And just to humour you... Here's my "RegExp" for my "clean" example
(return) ({1,}((.[^)]{1,}))(.{1,}))(.{1,})){1,}
$1 $2 $3 $4 // output
oh... Forgot to mention
(!(testCrossZ()))
Might appear at times as well but those aren't as big of an issue to clean up manually if needed.
P.S... There is a "LOT" of occurances of the redundant parentheses... Like... Maybe thousands... Most likely thousands.
Not sure if it applies for actionscript, but for Java you can do: Main Menu | Analyze | Run Inspection by Name | type "parentheses" | select "Unnecessary parentheses" | run in the whole project and fix all problems
Result:
return getHumanReadableLine("avHardwareDisable") + getHumanReadableLine("hasAccessibility")
+ getHumanReadableLine("hasAudio") + getHumanReadableLine("hasAudioEncoder")
+ getHumanReadableLine("hasEmbeddedVideo") + getHumanReadableLine("hasIME")
+ getHumanReadableLine("hasMP3") + getHumanReadableLine("hasPrinting")
+ getHumanReadableLine("hasScreenBroadcast") + getHumanReadableLine("hasScreenPlayback")
+ getHumanReadableLine("hasStreamingAudio") + getHumanReadableLine("hasStreamingVideo")
+ getHumanReadableLine("hasTLS") + getHumanReadableLine("hasVideoEncoder")
+ getHumanReadableLine("isDebugger") + getHumanReadableLine("language")
+ getHumanReadableLine("localFileReadDisable") + getHumanReadableLine("manufacturer")
+ getHumanReadableLine("os") + getHumanReadableLine("pixelAspectRatio")
+ getHumanReadableLine("playerType") + getHumanReadableLine("screenColor")
+ getHumanReadableLine("screenDPI") + getHumanReadableLine("screenResolutionX")
+ getHumanReadableLine("screenResolutionY") + getHumanReadableLine("version");
I honestly haven't understood the exact form of the output format that you wanted but as per starters at least clearing off the unnecessary parenthesis can be done with pure JavaScript as follows.
var text = 'return ((((((((((((((((((((((((((getHumanReadableLine("avHardwareDisable") + getHumanReadableLine("hasAccessibility")) + getHumanReadableLine("hasAudio")) + getHumanReadableLine("hasAudioEncoder")) + getHumanReadableLine("hasEmbeddedVideo")) + getHumanReadableLine("hasIME")) + getHumanReadableLine("hasMP3")) + getHumanReadableLine("hasPrinting")) + getHumanReadableLine("hasScreenBroadcast")) + getHumanReadableLine("hasScreenPlayback")) + getHumanReadableLine("hasStreamingAudio")) + getHumanReadableLine("hasStreamingVideo")) + getHumanReadableLine("hasTLS")) + getHumanReadableLine("hasVideoEncoder")) + getHumanReadableLine("isDebugger")) + getHumanReadableLine("language")) + getHumanReadableLine("localFileReadDisable")) + getHumanReadableLine("manufacturer")) + getHumanReadableLine("os")) + getHumanReadableLine("pixelAspectRatio")) + getHumanReadableLine("playerType")) + getHumanReadableLine("screenColor")) + getHumanReadableLine("screenDPI")) + getHumanReadableLine("screenResolutionX")) + getHumanReadableLine("screenResolutionY")) + getHumanReadableLine("version")));',
r = /\(((getHumanReadableLine\("\w+"\)[\s\+]*)+)\)/g,
temp = "";
while (text != temp) {
temp = text;
text = text.replace(r,"$1");
}
document.write('<pre>' + text + '</pre>');
From this point on, it shouldn't be a big deal to convert the reduced text into the desired output format.

Extract number (with different delimiters) from string using REGEXP_SUBSTR in plsql

I need to extract patterned numbers from I/P string. I have the following patterns:
xxx-xxx-xxxx
xxx xxx-xxxx
xxx xxx xxxx
I am using this query to find matching string:
select REGEXP_substr('phn: 678 987-0987 Date: 12/2029',
'[0-9]{3}(\-|\ |\ )[0-9]{3}(\-|\--|\ )[0-9]{4}')
from dual;
I also want to extract the following patterns:
xxxxxx-xxxx
xxxxxxxxxx
etc...
Where do I modify the query?
Change your regex to,
[0-9]{3}(\-|\ |\ )?[0-9]{3}(\-|\--|\ )?-?[0-9]{4}
DEMO
(\-|\ |\ )? turns the whole group as optional. And -? turns - as optional. The function of ? after a character literal is, it makes the preceding token as optional.
Regular expressions are not always a good approach, since they are high resource consuming feature. I would still use old SUBSTR + INSTR technique :
16777216 * to_number(substr(ip, 1, instr(ip, '.', 1, 1) - 1))
+ 65536 * to_number(substr(ip, instr(ip, '.', 1, 1) + 1, instr(ip, '.', 1, 2) - instr(ip, '.', 1, 1) - 1))
+ 256 * to_number(substr(ip, instr(ip, '.', 1, 2) + 1, instr(ip, '.', 1, 3) - instr(ip, '.', 1, 2) - 1))
+ to_number(substr(ip, instr(ip, '.', 1, 3) + 1))
IP# is a simple 32-bit (4 bytes) integer; which is being presented in "dotted quad" format.
Each byte will contain a value between 0 and 255.
so converting to number & using between is as efficient as possible.

How do I capture all occurences in a string in Vim?

I want to capture all certain occurrences in a string in Vimscript.
example:
let my_calculation = '200/3 + 23 + 100.5/3 -2 + 4*(200/2)'
How can I capture all numbers (including dots if there are) before and after the '/'? in 2 different variables:
- output before_slash: 200100.5200
- output after slash 332
How can I replace them if a condition occurs?
p.e. if after a single '/' there is no '.' add '.0' after this number
I tried to use matchstring and regex but after trying and trying I couldn't resolve it.
A useful feature that can be taken advantage of in this case is substitution
with an expression (see :help sub-replace-\=).
let [a; b] = [[]]
call substitute(s, '\(\d*\.\?\d\+\)/\(\d*\.\?\d\+\)\zs',
\ '\=add(a,submatch(1))[1:0]+add(b,submatch(2))[1:0]', 'g')
To answer the second part of the question:
let my_calculation = '200/3 + 23 + 100.5/3 -2 + 4*(200/2)'
echo substitute(my_calculation, '\(\/[0-9]\+\)\([^0-9.]\|$\)', '\1.0\2', 'g')
The above outputs:
200/3.0 + 23 + 100.5/3.0 -2 + 4*(200/2.0)
Give this a try:
function! GetNumbers(string)
let pairs = filter(split(a:string, '[^0-9/.]\+'), 'v:val =~ "/"')
let den = join(map(copy(pairs), 'matchstr(v:val, ''/\zs\d\+\(\.\d\+\)\?'')'), '')
let num = join(map(pairs, 'matchstr(v:val, ''\d\+\(\.\d\+\)\?\ze/'')'), '')
return [num, den]
endfunction
let my_calculation = '200/3 + 23 + 100.5/3 -2 + 4*(200/2)'
let [a,b] = GetNumbers(my_calculation)
echo a
echo b