Regex to match words after dot until a whitespace occurs - regex

Given the following string
span.a.b this.is.really.confusing
I need to return the matches a and b. I've been able to get close with the following regex:
(?<=\.)[\w]+
But it's also matching is, really, and confusing. When I include a negative lookahead I get even closer, but I'm still not there.
(?<=\.)[\w]+(?=\s) # matches b, confusing
How can I match words after a dot until a whitespace occurs?

How can I match words after a dot until a whitespace occurs?
NB: this is language agnostic pseudo-code, but should work.
regex = "^[^\s.]+.(\S+).*"
targets = <extracted_group>.split(".")
Regex explanation:
"^": beings with
"[^\s.]+." 1 or more non-whitespace, non-period characters, followed by a period.
"(\S+)": group and capture all of the following non-whitespace characters
".*": matches 0 or more of any non-newline character
If the split function takes a regex instead of a string, you'll need to escape the '.' or use a character class.
NB: You can do it without the split, but I think that the split is more transparent.

I am not sure if this is good enough for all your possible cases, but it should work with the provided example:
\.([\w]+)\.([\w]+)\s
$1 = a, $2 = b

Related

Regex Extraction - Match before a space, or NOT before a space

Here are my potential inputs:
brian#muck.co, brian#gmail.com
brian#gmail.com, brian#muck.co
What I want to do is extract the #muck.co email address.
What I have tried is:
\s.*#muck.co
The problem is that this only grabs an email address if it is preceded by a space (so it would only match the second example input above). . . How would I write a Regex expression to match either inputs?
\s matches for a space, so you should wanted to use something like [^\s]*#muck.co - this means any number of not space caracters. [] - for a set of symbols, ^ - for negate effect.
It does not work for me, because \s in my regex flavour seems to not contain regular space, but this works [^[:space:]]\+#muck\.co. Also \+ instead of * for one or more non-space characters instead of any number and escape dot \. which unescaped stands for any single character.
You can use a negated character class to not cross the # and use either a word boundary at the end to prevent a partial word match:
[^\s#]+#muck\.co\b
Regex demo

Match a part of a string using regex

I have a string and would like to match a part of it.
The string is Accept: multipart/mixedPrivacy: nonePAI: <sip:4168755400#1.1.1.238>From: <sip:4168755400#1.1.1.238>;tag=5430960946837208_c1b08.2.3.1602135087396.0_1237422_3895152To: <sip:4168755400#1.1.1.238>
I want to match PAI: <sip:4168755400#
the whitespace can be a word so i would like to use .* but if i used that it matches most of the string
The example on that link is showing what i'm matching if i use the whitespace instead of .*
(PAI: <sip:)((?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4})#
The example on that link is showing what i'm trying to achieve with .* but it should only match PAI: <sip:4168755400#
(PAI:.*<sip:)((?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4})#
I tried lookaround but failing.
Any idea?
thanks
Matching the single space can be updated by using a character class matching either a space or a word character and repeat that 1 or more times to match at least a single occurrence.
Note that you don't have to escape the spaces, and in both occasions you can use an optional character class matching either a space or hyphen [ -]?
If you want the match only, you can omit the 2 capturing groups if you want to.
(PAI:[ \w]+<sip:)((?:\([2-9]\d{2}\) ?|[2-9]\d{2}[ -]?)[2-9]\d{2}[- ]?\d{4})#
Regex demo
The regex should be like
PAI:.*?(<sip:.*?#)
Explanation:
PAI:.*? find the word PAI: and after the word it can be anything (.*) but ? is used to indicate that it should match as few as possible before it found the next expression.
(<sip:.*?#) capturing group that we want the result.
<sip:.*?# find <sip: and after the word it can be anything .*? before it found #.
Example

How to extract dot(.) ended sentence?

I need to extract sentence ends with dot '.', but don't extract sentence ends in ' ...' (blank and three dots).
Example:
I love you.
I love you too ...
I want to match first sentence not second.
i image python style pseudo code:
for string in strings:
checker1 = (string == .)
if checker:
checekr2 = (prev_string(string) != blank)
if checker2:
extract_all_strings()
else:
pass
else:
pass
but I can't image regular expression code.
You can use the following regex:
[\w ]+\.(?!\.)
It matches one or more either Word character or Space, then it use a neagative look ahead to make sure there's only one dot.
You can use (?<! \.\.)\.$, see the demo.
Here you go with a very simple Regex:
[\w ]+\.$
Test the solution on Regex101.
[\w ] is a group of allowed characters, where \w stands for any character from [a-zA-Z0-9_] and stands for space itself.
[\w ]+ where + means that there the characters from the group described in the point above might appear between one and unlimited times.
\. is the dot itself which must be escaped, otherwise the dot . matches any character.
$ stands for the end of a string.
This together assures that only a sentence ending with exactly one dot will be caught.
Another and less strict approach might be allow anything, where the 2nd character from the end is not a dot and the last one is a dot (Regex101).
.+[^\.]\.$

Regex to match a word or a dot

This should be a fairly trivial question but I have spent quite some time and Im unable to do it -
If this is my string -
"this/DT word/NN is/VBZ a/DT dot/NN ./."
I want to extract the immediate neighbors of / , be it a word,comma or a full stop.
(\\w+)/(\\w+) gives the words before n after / but not the full stops etc.
I tried this - "\\.\\/\\.|(\\w+)/(\\w+)" for grabbing the full stops but doesn't seem to work.
Can someone help please.( I am trying this in R)
Thanks!
Note that \w only matches letters, digits and an underscore. A dot/period belongs to punctuation and can be captured with Perl-like \p{P} or POSIX class [:punct:]. Thus, theoretically, you could use something like ([\\w[:punct:]]+)/([\\w[:punct:]]+) (or even a more POSIXish ([[:alpha:][:punct:]]+)/([[:alpha:][:punct:]]+)), but I guess matching non-whitespace characters on both sides of / suits your purpose best.
Here is an alternative to the (\\S+)/(\\S+) regex:
([^\\s]+)/([^\\s]+)
See regex demo
The [^\s] means any symbol other than a whitespace. Note that \S means *any non-whitespace character.
If you can have no non-whitespace characters on either side of /, I believe
([^\\s]*)/([^\\s]*)
or
(\\S*)/(\\S*)
will work better for you since * will match 0 or more characters.
See another demo
You can use this regex
"(\\S+)/(\\S+)"
i.e. grab each non-space text before and after /.
RegEx Demo

Regular expression doesn't match if a character participated in a previous match

I have this regex:
(?:\S)\++(?:\S)
Which is supposed to catch all the pluses in a query string like this:
?busca=tenis+nike+categoria:"Tenis+e+Squash"&pagina=4&operador=or
It should have been 4 matches, but there are only 3:
s+n
e+c
s+e
It is missing the last one:
e+S
And it seems to happen because the "e" character has participated in a previous match (s+e), because the "e" character is right in the middle of two pluses (Teni s+e+S quash).
If you test the regex with the following input, it matches the last "+":
?busca=tenis+nike+categoria:"Tenis_e+Squash"&pagina=4&operador=or
(changed "s+e" for "s_e" in order not to cause the "e" character to participate in the match).
Would someone please shed a light on that?
Thanks in advance!
In a consecutive match the search for the next match starts at the position of the end of the previous match. And since the the non-whitespace character after the + is matched too, the search for the next match will start after that non-whitespace character. So a sequence like s+e+S you will only find one match:
s+e+S
\_/
You can fix that by using look-around assertions that don’t match the characters of the assumption like:
\S\++(?=\S)
This will match any non-whitespace character followed by one or more + only if it is followed by another non-whitespace character.
But tince whitespace is not allowed in a URI query, you don’t need the surrounding \S at all as every character is non-whitespace. So the following will already match every sequence of one or more + characters:
\++
You are correct: The fourth match doesn't happen because the surrounding character has already participated in the previous match. The solution is to use lookaround (if your regex implementation supports it - JavaScript doesn't support lookbehind, for example).
Try
(?<!\s)\++(?!\s)
This matches one or more + unless they are surrounded by whitespace. This also works if the plus is at the start or the end of the string.
Explanation:
(?<!\s) # assert that there is no space before the current position
# (but don't make that character a part of the match itself)
\++ # match one or more pluses
(?!\s) # assert that there is no space after the current position
If your regex implementation doesn't support lookbehind, you could also use
\S\++(?!\s)
That way, your match would contain the character before the plus, but not after it, and therefore there will be no overlapping matches (Thanks Gumbo!). This will fail to match a plus at the start of the string, though (because the \S does need to match a character). But this is probably not a problem.
You can use the regex:
(?<=\S)\++(?=\S)
To match only the +'s that are surrounded by non-whitespace.