Printing Javascript Template Strings with Line Breaks - javascript

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

Related

Regex replace not working the same in node as in console

I need to escape all commas in a sentence. My replace isn't working correctly in node, however in chrome console it's working fine.
Does anyone have a solution to this? It seems to be the same for all characters
let sentence = 'Hello, my name is Jim'
sentence.replace(/,/g, '\\,');
OUTPUT ON NODE TERM: 'Hello\\, my name is Jim'
The final string should be 'Hello\, my name is Jim'
Also, if anyone had an explanation as to why this works everywhere except the node console that'd be good!
Many thanks
That behaviour is explained here:
By default, repl.REPLServer instances format output using the util.inspect() method before writing the output to the provided Writable stream (process.stdout by default).
In other words, this is what's happening "under the hood":
const { inspect } = require('util')
let sentence = 'Hello, my name is Jim'
console.log( inspect( sentence.replace(/,/g, '\\,') ) );
inspect escapes strings, so \ becomes \\ (and the string also gets surrounded by quotation marks).
You can work around that by outputting the string yourself from the REPL:
console.log( sentence.replace(/,/g, '\\,') );
I suspect both Chrome and Node.js work the same, they just print the result differently.
When you just print the length of the string instead of the string itself, it is probably the same.
Node.js then prints the string in a format that is easy to copy & paste. It is a valid JavaScript string literal.
Chrome on the other hand prints all characters as they are, possibly marking the string start and end by using different colors. When you copy the string from the JavaScript console to the clipboard and then paste it somewhere, the backslash might double.

es6 multiline template strings with no new lines and allow indents

Been using es6 more and more for most work these days. One caveat is template strings.
I like to limit my line character count to 80. So if I need to concatenate a long string, it works fine because concatenation can be multiple lines like this:
const insert = 'dog';
const str = 'a really long ' + insert + ' can be a great asset for ' +
insert + ' when it is a ' + dog;
However, trying to do that with template literals would just give you a multi-line string with ${insert} placing dog in the resulting string. Not ideal when you want to use template literals for things like url assembly, etc.
I haven't yet found a good way to maintain my line character limit and still use long template literals. Anyone have some ideas?
The other question that is marked as an accepted is only a partial answer. Below is another problem with template literals that I forgot to include before.
The problem with using new line characters is that it doesn't allow for indentation without inserting spaces into the final string. i.e.
const insert = 'dog';
const str = `a really long ${insert} can be a great asset for\
${insert} when it is a ${insert}`;
The resulting string looks like this:
a really long dog can be a great asset for dog when it is a dog
Overall this is a minor issue but would be interesting if there was a fix to allow multiline indenting.
Two answers for this problem, but only one may be considered optimal.
Inside template literals, javascript can be used inside of expressions like ${}. Its therefore possible to have indented multiline template literals such as the following. The caveat is some valid js character or value must be present in the expression, such as an empty string or variable.
const templateLiteral = `abcdefgh${''
}ijklmnopqrst${''
}uvwxyz`;
// "abcdefghijklmnopqrstuvwxyz"
This method makes your code look like crap. Not recommended.
The second method was recommended by #SzybkiSasza and seems to be the best option available. For some reason concatenating template literals didn't occur to me as possible. I'm derp.
const templateLiteral = `abcdefgh` +
`ijklmnopqrst` +
`uvwxyz`;
// "abcdefghijklmnopqrstuvwxyz"
Why not use a tagged template literal function?
function noWhiteSpace(strings, ...placeholders) {
let withSpace = strings.reduce((result, string, i) => (result + placeholders[i - 1] + string));
let withoutSpace = withSpace.replace(/$\n^\s*/gm, ' ');
return withoutSpace;
}
Then you can just tag any template literal you want to have line breaks in:
let myString = noWhiteSpace`This is a really long string, that needs to wrap over
several lines. With a normal template literal you can't do that, but you can
use a template literal tag to allow line breaks and indents.`;
The provided function will strip all line breaks and line-leading tabs & spaces, yielding the following:
> This is a really long string, that needs to wrap over several lines. With a normal template literal you can't do that, but you can use a template literal tag to allow line breaks and indents.
I published this as the compress-tag library.

Reading From text file 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

Regex appears to ignore multiple piped characters

Apologies for the awkward question title, I have the following JavaScript:
var wordRe = new RegExp('\\b(?:(?![<^>"])fox|hello(?![<\/">]))\\b', 'g'); // Words regex
console.log('<span>hello</span> <hello>fox</hello> fox link hello my name is fox'.replace(wordRe, 'foo'));
What I'm trying to do is replace any word that isn't nested in a HTML tag, or part of a HTML tag itself. I.e I want to only match "plain" text. The expression seems to be ignoring the rule for the first piped match "fox", and replacing it when it shouldn't be.
Can anyone point out why this is? I think I might have organised the expression incorrectly (at least the negative lookahead).
Here is the JSFiddle.
I'd also like to add that I am aware of the implications of using regex with HTML :)
For your regex work, you want lookbehind. However, as of this writing, this feature is not supported in Javascript.
Here is a workaround:
Instead of matching what we want, we will match what we don't want and remove it from our input string. Later, we can perform the replace on the cleaned input string.
var nonWordRe = new RegExp('<([^>]+).*?>[^<]+?</\\1>', 'g');
var test = '<span>hello</span> <hello>fox</hello> fox link hello my name is fox';
var cleanedTest = test.replace(nonWordRe, '');
var final = cleanedTest.replace(/fox|hello/, 'foo'); // once trimmed final=='foo my name is foo'
NOTA:
I have build this workaround based on your sample. But here are some points that may need to be explored if you face them:
you may need to remove self closing tags (<([^>]+).*?/\>) from the test string
you may need to trim the final string (final)
you may need a descent html parser if tags can contain other tags as HTML allow this.
Javascript doesn't, again as of this writing, recursive patterns.
Demo
http://jsfiddle.net/yXd82/2/

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