I want to replace increment number using regular expression in TextPad. I have below code and I want increment number between tag <EndToEndId> and </EndToEndId> and number should remain 8 digits.
<PmtId>
<EndToEndId>80000001</EndToEndId>
</PmtId>
<PmtTpInf>
<Prtry>PM</Prtry>
</PmtTpInf>
<PmtId>
<PmtId>
<EndToEndId>80000002</EndToEndId>
</PmtId>
<PmtTpInf>
<Prtry>PM</Prtry>
</PmtTpInf>
<PmtId>
......
<PmtId>
<EndToEndId>800000010</EndToEndId>
</PmtId>
<PmtTpInf>
<Prtry>PM</Prtry>
</PmtTpInf>
<PmtId>
I have tried myself to come up with solution but after 80000009, it gives 800000010 which is 9 digit number.
I have provided below regular expression in Find And Replace option in TextPad.
Find What: (<EndToEndId>).*?(</EndToEndId>)
Replace With: (<EndToEndId>)\i(</EndToEndId>)
I have searched similar solution on Stackoverflow using Notepadd++ from Notepad++ incrementally replace
but it doens't give increment number when there are other tags like <PmtId>, <PmtTpInf>
Could you please help me to solve this issue as I have tried myself a lot and now asking on Stackoverflow. Thank you.
Do two passes.
The first pass as you are currently doing, producing results like:
80000001
80000009
800000010
800000099
8000000100
8000000999
then a second pass to correct the lengths:
Search: 80+(\d{6})\b
Replace: 8$1
Which produces the following result from the above sample intermediate output:
8000001
8000009
8000010
8000099
8000100
8000999
Related
I'm trying to write an xpath such that only nodes with text with numbers alone will be returned.
I wanted to use regex and was hoping this would work
td[matches(text(),'[\d.]')]
Can anyone please help me understand what am I doing wrong here
<tr>
<td>1</td>
<td>10</td>
<td>a</td>
</tr>
seams that you are missing quantification, [\d.] will match only 1 character, so 1 should be selected, 10 on the other site requires something like +, so try your regex like:
td[matches(text(),'\d+')]
Also that . in regex will make it capture non-digit characters, do not add that one.
You can test all your regex queries on regex101.
AFAIK so far Selenium support XPath 1.0 only, so matches() is not supported.
You can try below instead:
//td[number(.) >= 0 or number(.) < 0]
To match table cells with integers
Replace:
td[matches(text(),'[\d+]')]
with:
td[matches(text(),'\d+')]
Note: regex works only in xPath 2.0
I would like to drop a table cell from all of our XSL templates.
The code is the following:
<td width="100"><img src="/logos/code.png" border="0" width="100"/></td>
The code.png is different in every file. My regex is the following:
\<td.*\>\<img.*\/logos\/.*png.*\/\>\<\/td\>
I tested the expression on https://regex101.com/ and it matches to the above string, but when I try to find & replace with Notepad++, it gives me no match.
My xsl is all in one line, so line break cannot be the problem. Can someone help me, and give me a pattern that works in NP++?
You must not espace < and >.
Here is your regex : <td.*?><img.*?\/logos\/.*?png.*?\/><\/td>.
I also added ? to our .* to ensure it won't act as greedy.
Is there a way to insert the value from some sort of counter variable in Vim :substitute command?
For instance, to convert this document:
<SomeElement Id="F" ... />
<SomeElement Id="F" ... />
<SomeElement Id="F" ... />
to this resulting document:
<SomeElement Id="1" ... />
<SomeElement Id="2" ... />
<SomeElement Id="3" ... />
I imagine, the command would look like so:
:%s/^\(\s*<SomeElement Id="\)F\(".*\)$/\1<insert-counter-here>\2/g
I am using a very recent Windows build, from their provided installer. I strongly prefer not to install any additional tools. Ideally, I'd like to also avoid having to install scripts to support this, but I'm willing to, if it is the only way to do it.
It is possible to have a counter using the substitute-with-an-expression
feature (see :help sub-replace-\=). Unfortunately, since the
\= construct allows only expressions, the :let command cannot
be used, and therefore, a variable cannot not be set the usual way.
However, there is a simple trick to change the value of a variable in
expression if that variable is a list or a dictionary. In that case,
its contents could be modified by the map() function.
In such a manner, substitution for the case described in the question
would look as follows:
:let n=[0] | %s/Id="F"/\='Id="'.map(n,'v:val+1')[0].'"'/g
The tricky part here is in the substitute part of the replacement.
Since it starts with \=, the rest of it is interpreted
as an expression by Vim. Thus, 'Id="'.map(n, 'v:val+1').'"'
is an ordinary expression. Here a string literal 'Id="'
is concatenated (using the . operator) with return value
of the function call map(n, 'v:val+1'), and with another
string, '"'. The map function expects two arguments:
a list (as in this case) or a dictionary, and a string containing
expression that should be evaluated for each of the items in the given
list or dictionary. Special variable v:val denotes an individual
list item. So the 'v:val+1' string will be evaluated to a list item
incremented by one.
In this case, we can even simplify the command further:
:let n=[0] | %s/Id="\zsF\ze"/\=map(n,'v:val+1')[0]/g
The \zs and \ze pattern atoms are used to set the start and
the end of the pattern to replace, respectively (see :help /\zs
and :help /\ze). That way the whole search part of the substitute
command is matched, but only the part between \zs and \ze is
replaced. This avoids clumsy concatenations in the substitute
expression.
Either of these two short one-liners completely solves the issue.
For frequent replacements, one can even define an auxiliary function
function! Inc(x)
let a:x[0] += 1
return a:x[0]
endfunction
and make substitution commands even shorter:
:let n=[0] | %s/Id="\zsF\ze"/\=Inc(n)/g
Vim wiki instructions seems to be the easiest solution (at least for me).
Example below replaces all occurences of PATTERN with REPLACE_[counter] (REPLACE_1, REPLACE_2 etc.):
:let i=1 | g/PATTERN/s//\='REPLACE_'.i/ | let i=i+1
To answer the question it might look like this:
:let i=1 | g/SomeElement Id="F"/s//\='SomeElement Id="'.i.'"'/ | let i=i+1
Alternative solution
If anyone is interested in a solution with %s syntax I would advise to look at the #ib. answer which is:
:let n=[0] | %s/Id="\zsF\ze"/\=map(n,'v:val+1')/g
Hmm this it little tricky one. Here is what I got so far. Try these 2 map command in a vim session:
:nmap %% :let X=1<cr>1G!!
:nmap !! /^\s*<SomeElement Id="F"<cr>:s/F"/\=X.'"'/<cr>:let X=X+1<cr>!!
Once that is there press %% to start the fun part :)
It makes your given file as:
<SomeElement Id="1" ... />
<SomeElement Id="2" ... />
<SomeElement Id="3" ... />
<SomeElement Id="4" ... />
Explanation:
First nmap command is mapping following sequences to keystrokes %%:
initializing variable X to 1
moving to start of first file
calling another mapped keystroke !!
Second nmap command is mapping following sequences to keystrokes !!:
Search for next occurrence of pattern ^\s*<SomeElement Id="F"
If above pattern is found then search and replace F" by variable X and a quote "
increment the vim variable X by 1
Recursively call itself by making a call to !!
Single dot . is used for concatenation of strings in vim, very similar to php
This recursive calls stop when pattern ^\s*<SomeElement Id="F" is not found anymore in the file.
Very simple solution. I've had to do this several times.
:let i=1 | g/^\(\s*<SomeElement Id="\)F\(".*\)$/s//\=submatch(1).i.submatch(2)/ | let i=i+1
Based off of the following tip. http://gdwarner.blogspot.com/2009/01/vim-search-and-replace-with-increment.html
Put this in your vimrc or execute it in your current session:
function! Inc(x)
let a:x[0] += 1
return a:x[0]
endfunction
function IncReplace(pos, behind, ahead, rep)
let poss=a:pos-1
let n=[poss]
execute '%s/' . a:behind . '\zs' . a:rep . '\ze' . a:ahead . '/\=Inc(n)/g'
endfunction
Then execute :call IncReplace(1, 'Id="', '"', 'F')
The first argument is the number you want to start from, the second is what you want to match behind the number, the third is what you want to match ahead of the number and the fourth is what you actually want to replace.
Maybe plugin increment.vim will help
I have a problem with SLRE library, I can't figure out how to stop grabbing everything after my match. Let's say I have a html output and somewhere in the middle of buffer there is line I want to parse
name="id" value="1a2b3c4d5e6f" />
Here is my regular expression
slre_compile(&test, "name=\"id\" value=\"(.*?)\" />")
I have read about greedy and non-greedy flags in other threads where people used to have similar problem as me, but in my case adding ? to the expression doesn't change anything.
SLRE returns me match starting from 1a2b3c4d5e6f" /> and shows rest of the html page ending on </html> tag, just I don't know why. It is cutting the beginning of the html source but leaves everything after my expression. I have also tried following regex
slre_compile(&test, "^.*?name=\"id\" value=\"(.*?)\" />.*?$")
and some others, modified with greedy and non-reedy flags, which gave me same results. Does anyone know why SLRE can't stop at " /> and continues capturing characters till the source string ends?
it seems that SLRE does not understand non-greedy qualifiers and parses .*? instead as if it were (?:.*)?. However, in this case \"[^\"]*\" should work...
From ant, we want to extract a line from an old /etc/shadow file, capturing the line for a specific user name, such as "manager". This is part of a backup/restore operation. What we used previously was not specific enough, so it would match users like "mymanager", so we tried to tighten it down by anchoring the start of the string to beginning of the line (typically "^"). This definitely did not work as we expected.
How can we anchor so that we get an exact match for a username? -- answered below.
First attempt, which gave the wrong result if we had a user of "mymanager" in the /etc/shadow file copy:
<loadfile property="oldPasswords" srcFile="${backup.dir}/shadow"/>
<propertyregex property="manager.backup" input="${oldPasswords}"
regexp="(manager\:.*)" select="\1" casesensitive="true" />
Second attempt, which failed because "^" is not interpreted in the normal regular expression way by default:
<loadfile property="oldPasswords" srcFile="${backup.dir}/shadow"/>
<propertyregex property="manager.backup" input="${oldPasswords}"
regexp="^(manager\:.*)" select="\1" casesensitive="true" />
Kobi suggested adding -> flags="m" <- which sounded good but ant reported that the flags option is not supported by propertyregex.
The final, successful, approach required inserting "(?m)" at the beginning of the regexp: That was the essential change.
<propertyregex property="manager.backup" input="${oldPasswords}"
regexp="(?m)^manager:.*$" select="\0" casesensitive="true" />
The regexp with propertyregex appears to follow the rules in this documentation of regular expressions in Java (search for "multiline" for example): http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Check the above document if you have similar questions about how to make propertyregex and regexp do what you want them to do!
THANKS! Solved.
Alan Carwile
I think the m(ultiline) flag is what you want to use and will give the start-of-line anchor the right behavior. It's possible to change flags within the regular expression with the syntax (?<flagstoturnon>-<flagstoturnoff>). So in your case, adding (?m) to the start of the regular expression (before the caret) should work.