im in need of help regarding a regex,
i have lines that look like this
1995
80
100
83
3
Etc
I need them to becomes
1.9.9.5
8.0
1.0.0
8.3
3
and i dont know how the single numbers would turn out with a regex to do this
I dont have experience with regex, which is why im posting here, any help is greatly appreciated, thank you
Use lookaround to do such job.
Ctrl+H
Find what: (?<=\d)(?=\d)
Replace with: .
Replace all
Explanation:
(?<= : start lookbehind, make sure before we have
\d : a digit
) : end lookbehind
(?= : start lookahead, make sure after we have
\d : a digit
) : end lookahead
Replacement:
a dot, that will be inserted between 2 digits.
Result for given example:
1.9.9.5
8.0
1.0.0
8.3
3
Find what: (?=\d\d+)(.)
Replace with: \1\.
uses a non consuming group to first assert that the line has more than one digit,
then captures each digit and replaces it with the digit followed by a .
for the last digit in a number with more than one ie 234, it fails the assertion because the regex engine has already parsed 234 and so treats it as 4.
Related
I want to find version numbers in a long string.
Example: "Hellothisisastring 12.3 blabla"
I need to find a substring that is a version number but does not start with "/".
Example: "Hellothisisastring /12.3 blabla"
shouldn't match.
I already build following regex:
[0-9]+.[0-9]
How can I detect a that the version number does not start with "/". The problem is that it is not at the beginning of the string. I already tried with negative lookahead.
(?!/)[0-9]+.[0-9] still matches with a slash before.
Thanks for any help :)
You need to use a lookbehind and include a digit pattern to also fail the positions right after digits:
(?<![\d\/])[0-9]+\.[0-9]+
See the regex demo.
Also, you may match any amount of . + digits using
(?<![\d\/])[0-9]+(?:\.[0-9]+)+
See this regex demo. Details:
(?<![\d\/]) - a negative lookbehind that fails the match if there is a digit or / immediately to the left of the current location
[0-9]+ - one or more digits
(?:\.[0-9]+)+ - one or more sequences of a . and one or more digits.
I'm using regex in powershell 5.1.
I need it to detect groups of numbers, but ignore groups followed or preceeded by /, so from this it should detect only 9876.
[regex]::matches('9876 1234/56',‘(?<!/)([0-9]{1,}(?!(\/[0-9])))’).value
As it is now, the result is:
9876
123
6
More examples: "13 17 10/20" should only match 13 and 17.
Tried using something like (?!(\/([0-9]{1,}))), but it did not help.
You may use
\b(?<!/)[0-9]+\b(?!/[0-9])
See the regex demo
Alternatively, if the numbers can be glued to text:
(?<![/0-9])[0-9]+(?!/?[0-9])
See this regex demo.
The first pattern is based on word boundaries \b that make sure there are no letters, digits and _ right before and after an expected match. The second one just makes sure there are no digits and / on both ends of the match.
Details
(?<![/0-9]) - a negative lookbehind making sure there is no digit or / immediately to the left of the current location
[0-9]+ - one or more digis
(?!/?[0-9]) - a negative lookahead making sure there is no optional / followed with a digit immediately to the right of the current location.
I have to find the first 11 digits and cut everything that follows from the eleventh digit.
I've been trying to do it with this pattern :/^(\d{11}.*?). However, doesn't work.
You know what I'm doing wrong?
Depending on your regex flavour, you could use:
Find: ^\d{11}\K.+$
Replace: NOTHING
Explanation:
^ : beginning of line
\d{11} : 11 digits
\K : forget all we have seen until this position
.+ : 1 or more any character
$ : end of line
If you want to match first characters, you need to use anchor ^ that will anchor match at the beginning of the string.
If you want to match something and then reuse it, then you need to capture it isnide capturing group and use it in sbstitution with \1.
If you want to capture eleven digits - \d{11} will work for you.
So to sum up, you need pattern ^(\d{11}).* and replace with \1. .* will match 0 or more characters (any).
After lot of trying, It actually works with this one:
^(?=(\d{11})).+?
I'm trying to find all single numbers (with the use of vim):
numbers at start of line
numbers at end of line
the number has to be followed and proceded by a non number
but may not be folowed or proceded with a "dot" and a number or a "," and a number.
this is correct
7
word7
7word
7.
.7
a,7
word7word
word 7 word
7-7
but not this
7.7
7,7
77
Can anyone help me and explain the regex?
EDIT:
may'be I've found it with the help of an answer below about atomic grouping. Vim does support it:
\(\d\.\|\d\,\|\d\)\#<!\d\(\.\d\|\,\d\|\d\)\#!
You can try this:
\v%(\d+%(\.|,))#<!\d#<!\d+#>%(%(\.|,)\d)#!
Explanation:
\v turns very magic : no need of many backslashes
the % signs are optional (make groups in parentheses non-matching)
(\d+(\.|,)#<! : not preceded with digits then . or ,
\d#<! : not preceded with a digit (be sure we are at the first digit
\d+#> : consume all digits (#> ensures that, see :help /\#>)
((\.|,)\d)#! : after that, no dot or comma followed by a digit.
Give this a whirl:
^(?!\d(\.|\,)?\d)(((\D*?)\d(\D*?))|(\d(\D*?)\d))$
And let me know if you'd like an explanation.
Try this one:
\(\d[\.,]\)\#<!\d\#<!\d\d\#!\([\.,]\d\)\#!
Explanation:
It looks for digits (\d) that are not preceeded by a '.' or ',' followed by a digit (\(\d[\.,]\)\#<!) or a single digit (\d\#<!), and is not followed by '.' or ',' followed by a digit (\([\.,]\d\)\#!) or a single digit (\d\#!).
This one is straight from my vim so it should work in yours.
I've been able to stumble my way through regular expressions for quite some time, but alas, I cannot help a friend in need.
My "friend" is trying to match all lines in a text file that match the following criteria:
Only a 7 to 10 digit number (0123456 or 0123456789)
Only a 7 to 10 digit number, then a dash, then another two digits (0123456-01 or 0123456789-01)
Match any of the above except where the words Code/code or Passcode/passcode is before the numbers to match (Such as "Access code: 16434629" or "Passcode 5253443-12")
EDIT: Only need the numbers that match, nothing else.
Here is the nastiest regex I have ever seen that "he" gave me:
^(?=.*?[^=/%:]\b\d{7,10}((\d?\d?)|(-\d\d))?\b)((?!Passcode|passcode|Code|code).)*$
...
Question: Is there a way to use a short regex to find all lines that meet the above criteria?
Assume PCRE. My friend thanks you in advance. ;-)
BTW - I have not been able to find any other questions listed in stackoverflow.com or superuser.com which can answer this question accurately.
EDIT: I'm using Kodos Python Regex Debugger to validate and test the regex.
(?<!(?:[Pp]asscode|[Cc]ode).*)[0-9]{7,10}(?:-[0-9]{2})?
Commented version:
(?<! # Begin zero-width negative lookbehind. (Makes sure the following pattern can't match before this position)
(?: # Begin non-matching group
[Pp]asscode # Either Passcode or passcode
| # OR
[Cc]ode # Either Code or code
) # End non-matching group
.* # Any characters
) # End lookbehind
[0-9]{7,10} # 7 to 10 digits
(?: # Begin non-matching group
-[0-9]{2} # dash followed by 2 digits
) # End non-matching group
? # Make last group optional
Edit: final version after comment discussion -
/^(?!\D*(?:[Pp]asscode|[Cc]ode))\D*([0-9]{7,10}(?:-[0-9]{2})?)/
(result in first capture buffer)
You can get by with a nasty regex you have to get help with ...
... or you can use two simple regexes. One that matches what you want, and one that filters what you don't want. Simpler and more readable.
Which one would you like to read?
$foo =~ /(?<!(?:[Pp]asscode|[Cc]ode).*)[0-9]{7,10}(?:-[0-9]{2})?/
or
$foo =~ /\d{7,10}(-\d{2})?/ and $foo !~ /(access |pass)code/i;
Edit: case-insensitivity.