Am trying to find a regex expression for this result:
string => should be matched (a single word or set of words at the beginning or the ending)
string => should be matched (a single word or set of words in the middle)
{{string}} -- should not be matched (a single word or set of words surrounded by two "{}" should not be matched)
am using this regex in this function :
text = text.replace(RegExp("([^{]{2})[^(\d:)]" + aTags[index].textContent + "\w*
([^}]{2})", 'i'), "{{" + index + ":" + aTags[index].textContent + "}}");
the function should find the textContent of an 'a' tag in a 'text' string and replace it by adding a digit and ':' to the beginning of the textContent so that the result should be something like this :
some text => will became => {{1:some text}}
We can apply the good old *SKIP what's to avoid approach and throw everything that does not need to be replaced in the full match and capture the desired output in group 1:
{{[^}]+}}|(string)
To make this work effectively in JavaScript we have to use a .replace callback function:
const regex = /{{[^}]+}}|(string)/gm;
const str = `string
string
{{string}}`;
var index = 1; //this is your index var and is somehow set from outside
const result = str.replace(regex, function(m, group1) {
if (group1) return `{{${index}:${group1}}}`;
else return m;
});
console.log('Substitution result: ', result);
I had pseudo-coded this a bit since I cannot know where index and aTags[index].textContent is coming from. Adjust as needed.
You cannot use PCRE verbs like (*SKIP)(*F) in a JavaScript regex, i.e. you cannot skip a matched portion of text with the regex means only. In JavaScript, you may match and capture a part of the string you want to later analyze in the replacement callback method (JS String#replace accepts a callback as the replacement argument).
So, in your case the solution will look like
text = text.replace(RegExp("{{.*?}}|(" + aTags[index].textContent + ")", "gi"),
function ($0, $1) {
return $1 ? "{{" + index + ":" + $1 + "}}" : $0;
}
);
I understand the aTags[index].textContent value is alphanumeric, else, consider escaping it for use in a regex pattern.
The pattern will match a {{...}} substring having no } inside (with {{.*?}}) or (|) it will match and capture the text content ((aTags[index].textContent)) into Group 1. When you get a match, you need to pass 2 arguments to the callback, the whole match and Group 1 value. If Group 1 is not empty, you perform string manipulations, else, just insert the match back.
Related
I have some values like 10++10--10+-10-+.my question is how to replace these value into matched value using single reg expression.i need a answer like 10+10-10-10-.
its means
'++'='+',
'--'='-',
'+-'='-',
'-+'='-';
.please help me for solve my problem.
Match and capture the alternatives you need to replace with a specific string, and then use the replace callback to see which group matched and replace accordingly:
var s = '10++10--10+-10-+';
document.body.innerHTML = s.replace(/(\+\+)|([-+]-|-\+)/g, function(m, g1, g2) {
return g1? "+" : "-";
});
The (\+\+)|([-+]-|-\+) regex contains 2 alternative groups since there are 2 replacement patterns. Group 1 (\+\+) will match double pluses while Group 2 - ([-+]-|-\+) - matches and captures --, +- and -+.
A solution that is Regex only without callback function, so that it can be applicable in other languages that do not have regex replacement callbacks.
var s = '10++10--10+-10-+';
document.body.innerHTML = (s + "||||++=>+,+-=>-,-+=>-,--=>-" // Append replacements
).replace(/(\+\+|--|-\+|\+-)(?=[\s\S]*\1=>([^,]*))|\|\|\|\|[\s\S]*$/g, "$2"
// Perform replacements and remove replacements
)
I have the following string that I am attempting to match:
REQS_HOME->31
The following Javascript code is attempting to match this:
pathRegExPattern = '(' + docTypeHome + ')' + '(->)' + '(\d+)';
parsedResult = pathCookieValue.match(pathRegExPattern);
cookieToDelete = docType + '_ScrollPos_' + $3;
alert(parsedResult); // output - null
Assume the following:
docTypeHome = "REQS_HOME"
pathCookieValue = "REQS_HOME->31"
Firstly, I am not calling my match function properly. And secondly, how do I access the value where I am attempting to match the digit values using the backreference operator?
I need to extract the value 31.
Your digit-matching part needs to double-up on the backslashes:
pathRegExPattern = '(' + docTypeHome + ')' + '(->)' + '(\\d+)';
When you build up a regular expression from string parts, the string syntax itself will "eat" a backslash. Thus, the regex you were winding up with was just d+, without the backslash.
The "31" (or whatever the number ends up being) will be in parsedResult[3]. Note that it'll be a string, so if you need it to be a number you'll want to convert it first, via the Number constructor, or parseInt(), or whatever.
I am currently using the following JavaScript code:
concatedSubstring.replace(/\//g, '-').replace(/[A-Za-z]/g, function(c){
return c.toUpperCase().charCodeAt(0)-64;
});
...to take input in the format "1234/A", "22/B", etc. and output "1234-1" , "22-2", etc.
That is, / becomes -, and the letters become integers with A = 1, B = 2, etc.
I would like to change this so that if the input doesn't contain a "/" the output will still insert a "-" in the spot where the "/" should've been. That is, the input "1234A" should output "1234-1", or "22B" should output "22-2", etc.
The following should work even for inputs containing more than one of your number/letter pattern:
var input = "1234/B 123a 535d";
var replaced = input.replace(/(\d+)(\/?)([A-Za-z])/g, function(m,p1,p2,p3) {
return p1 + "-" + (p3.toUpperCase().charCodeAt(0)-64);
});
alert(replaced); // "1234-2 123-1 535-4"
The regex:
/(\d+)(\/?)([A-Za-z])/g
...will match one or more digits followed by an optional forward slash followed by a single letter, capturing each of those parts for later use.
If you pass a callback to .replace() then it will be called with arguments for the full match (which I'm ignoring for your requirement) and also for any sub-matches (which I use).
str = "1234/B"; or str = "1234B";
str.replace(/(\/[A-Z])|([A-Z])/g,"-"+parseInt(str.charCodeAt(str.indexOf(str.match(/[A-Z]/g)))-64))
You can also .replace(/([0-9])([a-zA-Z])/g,"$1-$2"): this turns a number adjacent to a letter into numberDASHletter, using backreferences (the $1 refers to whatever was in the first set of brackets, $2 to whatever was in the second set of brackets).
I'm trying to replace part of a string with the same number of dummy characters in JavaScript, for example: '==Hello==' with '==~~~~~=='.
This question has been answered using Perl and PHP, but I can't get it to work in JavaScript. I've been trying this:
txt=txt.replace(/(==)([^=]+)(==)/g, "$1"+Array("$2".length + 1).join('~')+"$3");
The pattern match works fine, but the replacement does not - the second part adds '~~' instead of the length of the pattern match. Putting the "$2" inside the parentheses doesn't work. What can I do to make it insert the right number of characters?
Use a function for replacement instead:
var txt = "==Hello==";
txt = txt.replace(/(==)([^=]+)(==)/g, function ($0, $1, $2, $3) {
return $1 + (new Array($2.length + 1).join("~")) + $3;
});
alert(txt);
//-> "==~~~~~=="
The issue with the expression
txt.replace(/(==)([^=]+)(==)/g, "$1"+Array("$2".length + 1).join('~')+"$3")
is that "$2".length forces $2 to be taken as a string literal, namely the string "$2", that has length 2.
From the MDN docs:
Because we want to further transform the result of the match before the final substitution is made, we must use a function.
This forces evaluation of the match before the transformation.
With an inline function as parameter (and repeat) -- here $1, $2, $3 are local variables:
txt.replace(/(==)([^=]+)(==)/g, (_,$1,$2,$3) => $1+'~'.repeat($2.length)+$3);
txt = '==Hello==';
//inline function
console.log(
txt.replace(/(==)([^=]+)(==)/g, (_, g1, g2, g3) => g1 + '~'.repeat(g2.length) + g3)
);
The length attribute is being evaluated before the $2 substitution so replace() won't work. The function call suggested by Augustus should work, another approach would be using match() instead of replace().
Using match() without the /g, returns an array of match results which can be joined as you expect.
txt="==Hello==";
mat=txt.match(/(==)([^=]+)(==)/); // mat is now ["==Hello==","==","Hello","=="]
txt=mat[1]+Array(mat[2].length+1).join("~")+mat[3]; // txt is now "==~~~~~=="
You excluded the leading/trailing character from the middle expression, but if you want more flexibility you could use this and handle anything bracketed by the leading/trailing literals.
mat=txt.match(/(^==)(.+)(==$)/)
A working sample uses the following fragment:
var processed = original.replace(/(==)([^=]+)(==)/g, function(all, before, gone, after){
return before+Array(gone.length+1).join('~')+after;
});
The problem in your code was that you always measured the length of "$2" (always a string with two characters). By having the function you can measure the length of the matched part. See the documentation on replace for further examples.
I am trying to do some string replacement with RegEx in Javascript. The scenario is a single line string containing long comma-delimited list of numbers, in which duplicates are possible.
An example string is: 272,2725,2726,272,2727,297,272 (The end may or may not end in a comma)
In this example, I am trying to match each occurrence of the whole number 272. (3 matches expected)
The example regex I'm trying to use is: (?:^|,)272(?=$|,)
The problem I am having is that the second and third matches are including the leading comma, which I do not want. I am confused because I thought (?:^|,) would match, but not capture. Can someone shed light on this for me? An interesting bit is that the trailing comma is excluded from the result, which is what I want.
For what it is worth, if I were using C# there is syntax for prefix matching that does what I want: (?<=^|,)
However, it appears to be unsupported in JavaScript.
Lastly, I know I could workaround it using string splitting, array manipulation and rejoining, but I want to learn.
Use word boundaries instead:
\b272\b
ensures that only 272 matches, but not 2725.
(?:...) matches and doesn't capture - but whatever it matches will be part of the overall match.
A lookaround assertion like (?=...) is different: It only checks if it is possible (or impossible) to match the enclosed regex at the current point, but it doesn't add to the overall match.
Here is a way to create a JavaScript look behind that has worked in all cases I needed.
This is an example. One can do many more complex and flexible things.
The main point here is that in some cases,
it is possible to create a RegExp non-capturing prefix
(look behind) construct in JavaScript .
This example is designed to extract all fields that are surrounded by braces '{...}'.
The braces are not returned with the field.
This is just an example to show the idea at work not necessarily a prelude to an application.
function testGetSingleRepeatedCharacterInBraces()
{
var leadingHtmlSpaces = ' ' ;
// The '(?:\b|\B(?={))' acts as a prefix non-capturing group.
// That is, this works (?:\b|\B(?=WhateverYouLike))
var regex = /(?:\b|\B(?={))(([0-9a-zA-Z_])\2{4})(?=})/g ;
var string = '' ;
string = 'Message has no fields' ;
document.write( 'String => "' + string
+ '"<br>' + leadingHtmlSpaces + 'fields => '
+ getMatchingFields( string, regex )
+ '<br>' ) ;
string = '{LLLLL}Message {11111}{22222} {ffffff}abc def{EEEEE} {_____} {4444} {666666} {55555}' ;
document.write( 'String => "' + string
+ '"<br>' + leadingHtmlSpaces + 'fields => '
+ getMatchingFields( string, regex )
+ '<br>' ) ;
} ;
function getMatchingFields( stringToSearch, regex )
{
var matches = stringToSearch.match( regex ) ;
return matches ? matches : [] ;
} ;
Output:
String => "Message has no fields"
fields =>
String => "{LLLLL}Message {11111}{22222} {ffffff}abc def{EEEEE} {_____} {4444} {666666} {55555}"
fields => LLLLL,11111,22222,EEEEE,_____,55555