Remove a long dash from a string in JavaScript? - javascript

I've come across an error in my web app that I'm not sure how to fix.
Text boxes are sending me the long dash as part of their content (you know, the special long dash that MS Word automatically inserts sometimes). However, I can't find a way to replace it; since if I try to copy that character and put it into a JavaScript str.replace statement, it doesn't render right and it breaks the script.
How can I fix this?
The specific character that's killing it is —.
Also, if it helps, I'm passing the value as a GET parameter, and then encoding it in XML and sending it to a server.

This code might help:
text = text.replace(/\u2013|\u2014/g, "-");
It replaces all – (–) and — (—) symbols with simple dashes (-).
DEMO: http://jsfiddle.net/F953H/

That character is call an Em Dash. You can replace it like so:
str.replace('\u2014', '');​​​​​​​​​​
Here is an example Fiddle: http://jsfiddle.net/x67Ph/
The \u2014 is called a unicode escape sequence. These allow to to specify a unicode character by its code. 2014 happens to be the Em Dash.

There are three unicode long-ish dashes you need to worry about: http://en.wikipedia.org/wiki/Dash
You can replace unicode characters directly by using the unicode escape:
'—my string'.replace( /[\u2012\u2013\u2014\u2015]/g, '' )

There may be more characters behaving like this, and you may want to reuse them in html later. A more generic way to to deal with it could be to replace all 'extended characters' with their html encoded equivalent. You could do that Like this:
[yourstring].replace(/[\u0080-\uC350]/g,
function(a) {
return '&#'+a.charCodeAt(0)+';';
}
);

With the ECMAScript 2018 standard, JavaScript RegExp now supports Unicode property (or, category) classes. One of them, \p{Dash}, matches any Unicode character points that are dashes:
/\p{Dash}/gu
In ES5, the equivalent expression is:
/[-\u058A\u05BE\u1400\u1806\u2010-\u2015\u2053\u207B\u208B\u2212\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u2E5D\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D]|\uD803\uDEAD/g
See the Unicode Utilities reference.
Here are some JavaScript examples:
const text = "Dashes: \uFF0D\uFE63\u058A\u1400\u1806\u2010-\u2013\uFE32\u2014\uFE58\uFE31\u2015\u2E3A\u2E3B\u2053\u2E17\u2E40\u2E5D\u301C\u30A0\u2E1A\u05BE\u2212\u207B\u208B\u3030𐺭";
const es5_dash_regex = /[-\u058A\u05BE\u1400\u1806\u2010-\u2015\u2053\u207B\u208B\u2212\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u2E5D\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D]|\uD803\uDEAD/g;
console.log(text.replace(es5_dash_regex, '-')); // Normalize each dash to ASCII hyphen
// => Dashes: ----------------------------
To match one or more dashes and replace with a single char (or remove in one go):
/\p{Dash}+/gu
/(?:[-\u058A\u05BE\u1400\u1806\u2010-\u2015\u2053\u207B\u208B\u2212\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u2E5D\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D]|\uD803\uDEAD)+/g

Related

Regex: get string between last character occurence before a comma

I need some help with Regex.
I have this string: \\lorem\ipsum\dolor,\\sit\amet\conseteteur,\\sadipscing\elitr\sed\diam
and want to get the result: ["dolor", "conseteteur", "diam"]So in words the word between the last backslash and a comma or the end.
I've already figured out a working test, but because of reasons it won't work in neitherChrome (v44.0.2403.130) nor IE (v11.0.9600.17905) console.There i'm getting the result: ["\loremipsumdolor,", "\sitametconseteteur,", "\sadipscingelitrseddiam"]
Can you please tell me, why the online testers aren't working and how i can achieve the right result?
Thanks in advance.
PS: I've tested a few online regex testers with all the same result. (regex101.com, regexpal.com, debuggex.com, scriptular.com)
The string
'\\lorem\ipsum\dolor,\\sit\amet\conseteteur,\\sadipscing\elitr\sed\diam'
is getting escaped, if you try the following in the browser's console you'll see what happens:
var s = '\\lorem\ipsum\dolor,\\sit\amet\conseteteur,\\sadipscing\elitr\sed\diam'
console.log(s);
// prints '\loremipsumdolor,\sitametconseteteur,\sadipscingelitrseddiam'
To use your original string you have to add additional backslashes, otherwise it becomes a different one because it tries to escape anything followed by a single backslash.
The reason why it works in regexp testers is because they probably sanitize the input string to make sure it gets evaluated as-is.
Try this (added an extra \ for each of them):
str = '\\\\lorem\\ipsum\\dolor,\\\\sit\\amet\\conseteteur,\\\\sadipscing\\elitr\\sed\\diam'
re = /\\([^\\]*)(?:,|$)/g
str.match(re)
// should output ["\dolor,", "\conseteteur,", "\diam"]
UPDATE
You can't prevent the interpreter from escaping backslashes in string literals, but this functionality is coming with EcmaScript6 as String.raw
s = String.raw`\\lorem\ipsum\dolor,\\sit\amet\conseteteur,\\sadipscing\elitr\sed\diam`
Remember to use backticks instead of single quotes with String.raw.
It's working in latest Chrome, but I can't say for all other browsers, if they're moderately old, it probably isn't implemented.
Also, if you want to avoid matching the last backslash you need to:
remove the \\ at the start of your regexp
use + instead of * to avoid matching the line end (it will create an extra capture)
use a positive lookahead ?=
like this
s = String.raw`\\lorem\ipsum\dolor,\\sit\amet\conseteteur,\\sadipscing\elitr\sed\diam`;
re = /([^\\]+)(?=,|$)/g;
s.match(re);
// ["dolor", "conseteteur", "diam"]
You may try this,
string.match(/[^\\,]+(?=,|$)/gm);
DEMO

Match attribute value of XML string in JS

I've researched stackoverflow and find similar results but it is not really what I wanted.
Given an xml string: "<a b=\"c\"></a>" in javascript context, I want to create a regex that will capture the attribute value including the quotation marks.
NOTE: this is similar if you're using single quotation marks.
Currently I have a regular expression tailored to the XML specification:
[_A-Za-z][\w\.\-]*(?:=\"[^\"]*\")?
[_A-Za-z][\w\.\-]* //This will match the attribute name.
(?:=\"[^\"]*\")? //This will match the attribute value.
\"[^\"]*\" //This part concerns me.
My question now is, what if the xml string looks like this:
<shout statement="Hi! \"Richeve\"."></shout>
I know this is a dumb question to ask but I just want to capture rare cases that this scenario might happen (I know the coder can use single quotes on this scenario) but there are cases that we don't know the current value of the attribute given that the attribute value changes dynamically at runtime.
So to make this clearer, the result of that using the correct regex should be:
"Hi! \"Richeve\"."
I hope my question is clear. Thanks for all the help!
PS: Note that the language context is Javascript and I know it is tempting to use lookbehinds but currently lookbehinds are not supported.
PS: I know it is really hard to parse XML but I have an elegant solution to this :) so I just need this small problem to be solved. So this problem only main focus is capturing quotation marked string tokens containing quotation marks inside the string token.
The standard pattern for content with matching delimiters and embedded escaped delimiters goes like this:
"[^"\\]*(?:\\.[^"\\]*)*"
Ignoring the obvious first and last characters in the pattern, here's how the rest of the pattern works:
[^"\\]*: Consume all characters until a delimiter OR backslash (matching Hi! in your example)
(?:\\.[^"\\]*)* Try to consume a single escaped character \\. followed by a series of non delimiter/backslash characters, repeatedly (matching \"Richeve first and then \". next in your example)
That's it.
You can try to use a more generic delimiter approach using (['"]) and back references, or you can just allow for an alternate pattern with single quotes like so:
("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')
Here's another description of this technique that might also help (see the section called Strings): http://www.regular-expressions.info/examplesprogrammer.html
Description
I'm pretty really sure embedding double quotes inside a double quoted attribute value is not legal. You could use the unicode equivalent of a double quote \x22 inside the value.
However to answer the question, this expression will:
allow escaped quotes inside attribute values
capture the attribute statement 's value
allow attributes to appear in any order inside the tag
will avoid many of the edge cases which will trip up pattern matching inside html text
doesn't use lookbehinds
<shout\b(?=\s)(?=(?:[^>=]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*?\sstatement=(['"])((?:\\['"]|.)*?)\1(?:\s|\/>|>))(?:[^>=]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/shout>
Example
Pretty Rubular
Ugly RegexPlanet set to Javascript
Sample Text
Note the difficult edge case in the first attribute :)
<shout onmouseover=' statement="He said \"I am Inside the onMouseOver\" " ; if ( 6 > a ) { funRotate(statement) } ; ' statement="Hi! \"Richeve\"." title="sometitle">SomeString</shout>
Matches
Group 0 gets the entire tag from open to close
Group 1 gets the quote surrounding the statement attribute value, this is used to match the closing quote correctly
Group 2 gets the statement attribute value which may include escaped quotes like \" but not including the surrounding quotes
[0][0] = <shout onmouseover=' statement="He said \"I am Inside the onMouseOver\" " ; if ( 6 > a ) { funRotate(statement) } ; ' statement="Hi! \"Richeve\"." title="sometitle">SomeString</shout>
[0][1] = "
[0][2] = Hi! \"Richeve\".

Regex simply not working in IE 8, 9 and 10

Here is our text to replace:
<IMG src="https://domain.com/images/siteheader.jpg">
Using javascript .replace, we try to replace with blank space using the following:
.replace ("/<A href=\"http:\/\/domain.com\"><IMG src=\"https:\/\/domain.com\/images\/siteheader.jpg\"><\/A>/i"," ");
In all other browsers this seems to work, but not in IE. I even tried using this online regex validator: http://www.online-toolz.com/tools/regexp-editor.php and it says it's valid. Kind of stumped. Is IE doing something out of the norm?
You either use a string (the literal form of which looks like "...") or a regular expression (the literal form of which looks like /.../) with replace. You're trying to do both simultaneously. Remove the quotes:
.replace (/<A href="http:\/\/domain.com"><IMG src="https:\/\/domain.com\/images\/siteheader.jpg"><\/A>/i, " ");
When you use a string, it's just matched literally, no regular expression processing is done.
I haven't validated the entire contents of the regex, just removed the surrounding " and removed the \ in front of the embedded ".
Regexes are literals and should not have quotes around them:
.replace(/your regex here/,'replacement')
That being said, where is the text coming from? If it's coming from .innerHTML, browsers may return a string that is different from what you literally have in the source (for instance, attribute names may be uppercased, or the attributes themselves swapped. I believe older versions of IE strip out quotes around single-word attribute values, which would also mess with your regex.
In short, you should not use a regex for this. You could try this instead:
var toRemove = document.querySelector("a[href='http://domain.com']"),
parent = toRemove.parentNode;
parent.removeChild(toRemove);

JS regex syntax

I want to do a regex pattren in JavaScript that will allow a string only with numbers and this signs: ()+ and a space. In a length of 5-16 chars.
Please Note: the order of the chars in the string is not important.
What is the right pattren for this?
Thanks
How about this:
/^[0-9 ()+]{5,16}$/
It's quite easy to construct it by yourself. )
First, as you impose strict limits, you should check the whole string, so regex should be wrapped into /^...$/.
Second, if you only need some specific characters, you should use character class: write all them down into [...] form. In your case you can shortcut: replace /^[0123456789 ()+]$/ with just /^[0-9 ()+]$/.
Finally, state some quantitative limits with {$min, $max} form: in your case that would be {5,16}. Mix this into what you got so far - and voila! You solved the task. )
if( myText.match(/\A[0-9 ()+]{5,16}\Z/) ) {
// Yay!
}
While it was correctly pointed out that I was missing anchor characters, using ^$ will only match the line of a string, therefor, "823479898237\n328742987" will match despite being too long.

Regex validation rules

I'm writing a database backup function as part of my school project.
I need to write a regex rule so the database backup name can only contain legal characters.
By 'legal' I mean a string that doesn't contain ANY symbols or spaces. Only letters from the alphabet and numbers.
An example of a valid string would be '31Jan2012' or '63927jkdfjsdbjk623' or 'hello123backup'.
Here's my JS code so far:
// Check if the input box contains the charactes a-z, A-Z ,or 0-9 with a regular expression.
function checkIfContainsNumbersOrCharacters(elem, errorMessage){
var regexRule = new RegExp("^[\w]+$");
if(regexRule.test( $(elem).val() ) ){
return true;
}else{
alert(errorMessage);
return false;
}
}
//call the function
checkIfContainsNumbersOrCharacters("#backup-name", "Input can only contain the characters a-z or 0-9.");
I've never really used regular expressions before though, however after a quick bit of googling i found this tool, from which I wrote the following regex rule:
^[\w]+$
^ = start of string
[/w] = a-z/A-Z/0-9
'+' = characters after the string.
When running my function, the whatever string I input seems to return false :( is my code wrong? or am I not using regex rules correctly?
The problem here is, that when writing \w inside a string, you escape the w, and the resulting regular expression looks like this: ^[w]+$, containing the w as a literal character. When creating a regular expression with a string argument passed to the RegExp constructor, you need to escape the backslash, like so: new RegExp("^[\\w]+$"), which will create the regex you want.
There is a way to avoid that, using the shorthand notation provided by JavaScript: var regex = /^[\w]+$/; which does not need any extra escaping.
It can be simpler. This works:
function checkValid(name) {
return /^\w+$/.test(name);
}
/^\w+$/ is the literal notation for new RegExp(). Since the .test function returns a boolean, you only need to return its result. This also reads better than new RegExp("^\\w+$"), and you're less likely to goof up (thanks #x3ro for pointing out the need for two backslashes in strings).
The \w is a synonym for [[:alnum:]], which matches a single character of the alnum class. Note that using character classes means that you may match characters that are not part of the ASCII character encoding, which may or may not be what you want. If what you really intend to match is [0-9A-Za-z], then that's what you should use.
When you declare the regex as a string parameter to the RegExp constructor, you need to escape it. Both
var regexRule = new RegExp("^[\\w]+$");
...and...
var regexRule = new RegExp(/^[\w]+$/);
will work.
Keep in mind though, that client side validation for database data will never be enough, as the validation is easily bypassed by disabling javascript in the browser, and invalid/malicious data can reach your DB. You need to validate the data on the server side, but preventing the request with invalid data, but validating client side is good practice.
This is the official spec: http://dev.mysql.com/doc/refman/5.0/en/identifiers.html but it's not very easily converted to a regular expression. Just a regular expression won't do it as there are also reserved words.
Why not just put it in the query (don't forget to escape it properly) and let MySQL give you an error? There might for instance be a bug in the MySQL version you're using, and even though your check is correct, MySQL might still refuse.

Categories

Resources