Reading From text file Javascript - javascript

Okay, this may be hard to explain.
The Passwords don't work the usernames do.
I am reading from a text file.
"username,password" is the structure for the below is the text file
John,BOL12345
Mary2,BOL77777
Anna,BOL54321
test,BOL12345
The top 3 do not work alone i only need the top 3
but once i add the "test,BOL12345"
the password BOL12345 does work
but without the "test,BOL12345" The password "BOL12345" does not work or any of the other ones
I am doing this all in javascript below will be the code snippet.. please ask any questions as i do not understand why this happens.
The JavaScript Below
The "lines" = the text file above
lines = x.responseText.split("\n");
for (i=0; i < lines.length; i++)
{
test1 = lines[i].split(",")
username.push(test1[0]);
password.push(test1[1]);
}
var tempUsername = document.getElementById('username').value;
var tempPassword = document.getElementById('password').value;
var arraycontainsusername = (username.indexOf(tempUsername) > -1);
var arraycontainspassword = (password.indexOf(tempPassword) > -1);
alert(password);
if (arraycontainsusername && arraycontainspassword) {
window.location.href = "listing.htm";
};

Educated guess: your file is using \r\n. since you're splitting by \n the \r is left in and corrupts each string. try splitting by \r\n and see what happens. That would explain why adding the last line would work, since there's no newline at the end there won't be a trailing character to mess up the indexOf search.
different operating systems handle text files differently. Windows uses CRLF (Carriage Return Line Feed) to jump to the next line, while *NIX variants use LF. old MacOS versions use CR. Your code was assuming the file came from a *NIX environment, where LF (or \n) is the norm, when it came from a windows environment, where CRLF (or \r\n) is the norm (not accurate since you can make text files with LF in windows and with CRLF in *NIX, buy you get the picture).
To handle all cases correctly, I'd recommend normalizing the string before working on it:
x.responseText.replace(/\r\n|\r(?!\n)/g, '\n').split('\n');
that seemingly chinese string in the middle is actually a regular expression that matches either \r\n or \r (but only when \r isn't followed by \n). this way you can replace all your CRLFs and CRs to LF and handle text coming from any environment.
you can simplify that regex because of the order of the tokens, to /\r\n|\r/, but I'm leaving it in because it illustrates a neat concept (lookaheads - that bit (?!\n) says if and only if not immediately followed by a \n). With that said /\r\n|\r/ will perform better, especially when handling large files

Related

Why do I need to replace \n with \n?

I have a line of data like this:
1•#00DDDD•deeppink•1•100•true•25•100•Random\nTopics•1,2,3,0•false
in a text file.
Specifically, for my "problem", I am using Random\nTopics as a piece of text data, and I then search for '\n', and split the message up into two lines based on the placement of '\n'.
It is stored in blockObj.msg, and I search for it using blockObj.msg.split('\n'), but I kept getting an array of 1 (no splits). I thought I was doing something fundamentally wrong and spent over an hour troubleshooting, until on a whim, I tried
blockObj.msg = blockObj.msg.replace(/\\n/g, "\n")
and that seemed to solve the problem. Any ideas as to why this is needed? My solution works, but I am clueless as to why, and would like to understand better so I don't need to spend so long searching for an answer as bizarre as this.
I have a similar error when reading "text" from an input text field. If I type a '\n' in the box, the split will not find it, but using a replace works (the replace seems pointless, but apparently isn't...)
obj.msg = document.getElementById('textTextField').value.replace(/\\n/g, "\n")
Sorry if this is jumbled, long time user of reading for solutions, first time posting a question. Thank you for your time and patience!
P.S. If possible... is there a way to do the opposite? Replace a real "\n" with a fake "\n"? (I would like to have my dynamically generated data file to have a "\n" instead of a new line)
It is stored in blockObj.msg, and I search for it using blockObj.msg.split('\n'),
In a JavaScript string literal, \n is an escape sequence representing a new line, so you are splitting the data on new lines.
The data you have doesn't have new lines in it though. It has slash characters followed by n characters. They are data, not escape sequences.
Your call to replace (blockObj.msg = blockObj.msg.replace(/\\n/g, "\n")) works around this by replacing the slashes and ns with new lines.
That's an overcomplicated approach though. You can match the characters you have directly. blockObj.msg.split('\\n')
in your text file
1•#00DDDD•deeppink•1•100•true•25•100•Random\nTopics•1,2,3,0•false
means that there are characters which are \ and n thats how they are stored, but to insert a new line character by replacement, you are then searching for the \ and the n character pair.
obj.msg = document.getElementById('textTextField').value.replace(/\\n/g, "\n")
when you do the replace(/\\n/g, "\n")
you are searching for \\n this is the escaped version of the string, meaing that the replace must find all strings that are \n but to search for that you need to escape it first into \\n
EDIT
/\\n/g is the regex string..... \n is the value... so /\REGEXSTUFFHERE/g the last / is followed by regex flags, so g in /g would be global search
regex resources
test regex online

Printing Javascript Template Strings with Line Breaks

Is there a way to print (using console.log) javascript template strings, applying the substitutions when it's the case, but considering the linebreaks '\n' when printing?
For instance, when I have the following:
let someVar = 'a';
let tsString = `here goes ${someVar}
some other line
some other line`;
console.log(tsString);
I'd like it to print WITH the linebreaks, not printing the \n's instead.
I think there could be some transformation between template strings and regular strings, but I could not find it.
*** EDIT: It happens on Terminal, not browser. Running a NodeJS app. Sorry for not specifying that, I assumed that what I wanted would be JS-specific, not node's (at least the solution).
I think it may be related to the OS you're using since Windows and Mac have different character lengths for their line endings.
To answer the particular question which seems to work for me.
const os = require('os');
let someVar = 'a';
let tsString = `here goes ${someVar} ${os.EOL} some other line ${os.EOL} some other line`;
console.log(tsString);
You can read about the os middleware on the nodejs docs here: https://nodejs.org/api/os.html#os_os_eol
This seems to be a similar duplicate of: How do I create a line break in a JavaScript string to feed to NodeJS to write to a text file?
Another solution besides adding to the string \n, which is the standard solution is as follows:
You've got there a character for new line:
(I cannot paste that character in here as the markdown kills it)
You could capture it in a variable and insert it in a template string:
const newline = tsString[12];
const myString = `Hello ${newline} World!`;
Hope it helps.
You should try replacing the EOL based on where you are taking the content, forms as a standard should support the CRLF \r\n as per the spec (https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4)
Use the following regex to replace all occurences. \n would match EOL and /gm would match all
let someVar = 'a';
let tsString = `here goes ${someVar}
some other line
some other line`;
//For terminal (detects EOL on it's own)
console.log(tsString);
let txtString = tsString.replace(/\n/gm, `\r\n`);
// Works in terminal and in textarea
console.log(txtString);
//For html content, redundant but if it's just html you want!
let htmlString = tsString.replace(/\n/gm, `<br>`);
console.log(htmlString);
You can embed the data inside string like
const myTemplateString = My sample text 1 is ${one}
My second line 2 is ${two}
console.log(myTemplateString) the ES6 will preserve white spaces and hence you can get the required line breaks.
refer this article

End-of-string regex match too slow

Demo here. The regex:
([^>]+)$
I want to match text at the end of a HTML snippet that is not contained in a tag (i.e., a trailing text node). The regex above seems like the simplest match, but the execution time seems to scale linearly with the length of the match-text (and has causes hangs in the wild when used in my browser extension). It's also equally slow for matching and non-matching text.
Why is this seemingly simple regex so bad?
(I also tried RegexBuddy but can't seem to get an explanation from it.)
Edit: Here's a snippet for testing the various regexes (click "Run" in the console area).
Edit 2: And a no-match test.
Consider an input like this
abc<def>xyz
With your original expression, ([^>]+)$, the engine starts from a, fails on >, backtracks, restarts from b, then from c etc. So yes, the time grows with size of the input. If, however, you force the engine to consume everything up to the rightmost > first, as in:
.+>([^>]+)$
the backtracking will be limited by the length of the last segment, no matter how much input is before it.
The second expression is not equivalent to the first one, but since you're using grouping, it doesn't matter much, just pick matches[1].
Hint: even when you target javascript, switch to the pcre mode, which gives you access to the step info and debugger:
(look at the green bars!)
You could use the actual DOM instead of Regex, which is time consuming:
var html = "<div><span>blabla</span></div><div>bla</div>Here I am !";
var temp = document.createElement('div');
temp.innerHTML = html;
var lastNode = temp.lastChild || false;
if(lastNode.nodeType == 3){
alert(lastNode.nodeValue);
}

Need to identify the non-matching character in regex

We use a regex to test for 'illegal' characters when a user provides a 'Version Name' before we save their content. The accepted characters are: A-Z, 0-9 and blank space. We test this using the following:
var version_name = document.getElementById('txtSaveVersionName').value;
if(version_name.search(/[^A-Za-z0-9\s]/)!= -1){
alert("Warning illegal characters have been removed etc");
version_name.replace(/[^A-Za-z0-9\s]/g,'');
document.getElementById('txtSaveVersionName').value = version_name;
}
This works fine when a user keys their version name. However the version name can also be populated from data taken from a dynamically populated select box - version names loaded in from our system.
When this occurs, the regexp throws out the space in the name. So "My Version" becomes "MyVersion"? This does not occur when the user types "My Version".
So it appears that the value taken from the select box contains a character that looks like a space but is not. I have copied this value from the text box into a unicode converter (http://rishida.net/tools/conversion/) that identifies the characters underlying values and both sets are reported as 0020 (space), yet only ones throws an exception??
Is there a way to identify what the character is that is causing this issue?
Any thoughts greatly appreciated!
Cheers
Mark
Try:
var str= getSelectBoxValue();
var rez = "";
for (var i=0;i<str.length;i++)
rez = rez+str[i]+"["+str.charCodeAt(i)+"]";
alert(rez);
It should give you the unicode values of all the characters in the string the way Javascript sees them. When you copy it from the screen, it could be the browser/OS that converts some weird UTF character into regular "0x20" character for some reason.
I noticed you have a bug in your code:
version_name.replace(/[^A-Za-z0-9\s]/g,'');
Should be
version_name = version_name.replace(/[^A-Za-z0-9\s]/g,'');
As, of course, replace creates a new string, it doesn't modify the existing string.
As you are finding that the replace sometimes works and sometimes doesn't I
would suspect that you have implimented this correctly in one place and incorrectly in another.

Need a regex for acceptable file names

I'm using Fancy Upload 3 and onSelect of a file I need to run a check to make sure the user doesn't have any bad characters in the filename. I'm currently getting people uploading files with hieroglyphics and such in the names.
What I need is to check if the filename only contains:
A-Z
a-z
0-9
_ (underscore)
- (minus)
SPACE
ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜäëïöü (as single and double byte)
Obviously you can see the difficult thing there. The non-english single and double byte chars.
I've seen this:
[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]
And this:
[\x80-\xA5]
But neither of them fully cover the situation right.
Examples that should work:
fást.zip
abc.zip
ABC.zip
Über.zip
Examples that should NOT work:
∑∑ø∆.zip
¡wow!.zip
•§ªº¶.zip
The following is close, but I'm NO RegEx'pert, not even close.
var filenameReg = /^[A-Za-z0-9-_]|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF]+$/;
Thanks in advance.
Solution from Zafer mostly works, but it does not catch all of the other symbols, see below.
Uncaught:
¡£¢§¶ª«ø¨¥®´åß©¬æ÷µç
Caught:
™∞•–≠'"πˆ†∑œ∂ƒ˙∆˚…≥≤˜∫√≈Ω
Regex:
var filenameReg = /^([A-Za-z0-9\-_. ]|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])+$/;
Alternation between two character classes (ie. [abc]|[def]) can be simplified to a single character class ([abcdef]) -- the first can be read as "(a or b or c) OR (d or e or f)"; the second as "(a or b or c or d or e or f)". What probably tripped up your regular expression is the unescaped dash in the first class -- if you want a literal dash, it should be the last character in the class.
So we'll modify your expression to get it working:
var filenameReg = /^[A-Za-z0-9_\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF-]+$/;
The problem now is that you're not accounting for the file extension, but that is an easy modification (assuming you're always getting .zip files):
var filenameReg = /^[A-Za-z0-9_\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF-]+\.zip$/;
Replace zip with another pattern if the extension differs.
It looks like it is the character ranges that are causing the problem, because they include some unallowable characters in between. Since you already have the list of allowable characters, the best thing would be to just use that directly:
var filenameReg = /^[A-Za-z0-9_\-\ ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜäëïöü]+$/;
The following should work:
var filenameReg = /^([A-Za-z0-9\-_. ]|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])+$/;
I've put \ next to - and grouped two expressions otherwise + sign doesn't affect the first expression.
EDIT 1 :I've also put . in the expression.
We have diffrent rules for diffrent platforms. But I think you mean long file names in windows. For that you can use following RegEx:
var longFilenames = #"^[^\./:*\?\""<>\|]{1}[^\/:*\?\""<>\|]{0,254}$";
NOTE: Instead of saying which Character is allowed, you need to say which ones are not allowed!
But keep in mind that this is not 100% complete RegEx. If you really want to make it complete you have to add exceptions for reserved names as well.
You can find more information about filename rules here:
http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx

Categories

Resources