Regex up to a special character and group of letters - regex

Using Regex, I'm attempting to get back the following (stars denote what I'd like to extract) from each string using a single Regex command:
FO4H56FD-BTU (Follow Home 56): PLTD8
\***********
FO4H56FD-SYH-BI (Follow Home 56 SYH): PLTD8
\***********
FO4H52FD-SZH-AG4R-BI (Follow Home 52 SAH): QQTD8
\****************
FO4H58FD-SGH: (Follow Home 58 TGT): PLTS8
\***********
For some reason I'm having a lot of difficulties. I've been using various methods and currently have =REGEXEXTRACT(A43,"(FO.+)\-BI") which isn't working. Mine also isn't looking for the : currently. I was using a | for multiple rules which didn't seem to work out.

You may use
=REGEXEXTRACT(A43,"^(.*?)(?:-BI)?(?:[ :]|$)")
Details:
^ - start of string
(.*?) - capturing group #1 matching any 0+ chars as few as possible
(?:-BI)? - an optional non-capturing group matching 1 or 0 occurrences of -BI substring
(?:[ :]|$) - either a space, : or end of string

Related

Need improvement on the Regex

I have wrote an easy regex for extracting user SC08.
https://regex101.com/r/L1DOzH/1/ Performance wise, its really bad taking around 1448 steps.
Jun 2 11:16:44 192.168.55.19 1 2020-06-02T10:16:43.721Z chisdsm#abcd.com dsm 4493 USR1278I [U#21513 sev="INFO" msg="user logged out due to inactivity" user="SC08"]
Jun 2 10:13:50 192.168.55.19 1 2020-06-02T09:13:50.297Z chisdsm#abcd.com dsm 4493 DO0426I [DA#21513 sev="INFO" msg="switch domain" admin="SC08"
Jun 2 10:13:43 192.168.55.19 1 2020-06-02T09:13:42.956Z chisdsm#abcd.com dsm 4493 DAO0267I [DA#21513 sev="INFO" msg="user logged in" admin="SC08" stime="2020-06-02 10:13:42.944" role="ALL_ADMIN" source="192.168.54.9"]
May 27 15:53:38 192.168.55.129 1 2020-05-27T14:53:37.669Z chisdsm#abcd.com dsm 4493 DAO0227I [DA#21513 sev="INFO" msg="delete file signature" user="SC08" filePath="/bin/rm"]
Alternation group as the first pattern in a regex cancels some optimizations that are in place for patterns that start with a more specific pattern.
Since your alternatives match = delimited strings, you may put it at the beginning of the pattern, and then use lookarounds, as in Michail's suggestion. Here is a small variation with 139 steps:
=(?:(?<=user=)"(?<user1>\w+)|(?<=admin=)"(?<user2>\w+))
See the regex demo. Details
= - an equals sign
(?:(?<=user=)"(?<user1>\w+)|(?<=admin=)"(?<user2>\w+)) - a non-capturing group:
(?<=user=) - user= must be immediately to the left of the current position
" - a " char
(?<user1>\w+) - Group "user1": 1+ word chars
| - or
(?<=admin=) - admin= must be immediately to the left of the current position
" - a " char
(?<user2>\w+) - Group "user2": 1+ word chars
If your matches are always preceded with a whitespace, use it as the first pattern:
\s(?:user="(?<user1>\w+)|admin="(?<user2>\w+))
See this regex demo, with 918 steps.
If you know the matches are somewhere close to the end of the line, use
.*\b(?:user="(?<user1>\w+)|admin="(?<user2>\w+))
See this regex demo, 568 steps. .* at the start will move the regex index at the end of a line/string and then backtrack to find either user= or admin=.

Regular expression for matching a specifc substring of a string

I have a log file that logs connection drops of computers in a LAN. I want to extract name of each computer from every line of the log file and for that I am doing this: (?<=Name:)\w+|(-PC)
The target text:
`[C417] ComputerName:KCUTSHALL-PC UserID:GO kcutshall Station 9900 (locked) LanId: | (11/23 10:54:09 - 11/23 10:54:44) | Average limit (300) exceeded while pinging www.google.com [74.125.224.147] 8x
[C445] ComputerName:FRONTOFFICE UserID:YB Yenae Ball Station 7C LanId: | (11/23 17:02:00) | Client is connected to agent.`
The problem is that some computer names have -PC in them and in some isn't. The expression I have created matches computer without -PC in their names but it if a computer has -PC in the name, it treats that as a separate match and I don't want that. In short, it gives me 3 matches, but I want only 2. That's why I need help here, I am beginner in regex.
You may use
(?<=Name:)\w+(?:-PC)?
Details
(?<=Name:) - a place immediately preceded with Name:
\w+ - 1+ word chars
(?:-PC)? - an optional non-capturing group that matches 1 or 0 occurrences of -PC substring.
Consider using word boundaries if you need to match PC as a whole word,
(?<=Name:)\w+(?:-PC\b)?
See the regex demo.

Regex to match *.sublime-settings files

Packages/Material Theme/widgets/Widget - Material-Theme.sublime-settings
Packages/DA UI/Widget - DA.sublime-settings
Packages/DA UI/Widget - DA (Windows).sublime-settings
Packages/TextMate/TextMate Syntax Definition (JSON).sublime-settings
Packages/DA UI/Widget - DA (Linux).sublime-settings
Packages/DA UI/Widget - DA (OSX).sublime-settings
Packages/User/YAML.sublime-settings
Could anyone have the time to implement a regex to match the first 4 and not the last 3.
rules
after Packages there must be at least one folder.
the folder right after Packages must not be "User".
the name (after the final slash) can optionally contain a pair of parenths right before the . that may not contain the name of other platforms; if the current platform is Windows, OSX and Linux are not accepted (we assume that the current platform is represented by a variable platform)
This is my try:
(?i)Packages/(?:[^/]+?/([^()]+?(?: \((?!OSX|Linux)\))?)\.sublime-settings)
It doesn't match 3 and 4 and matches the last.
Thanks in advance :)
You can use
(?i)^Packages/(?!User)(?:(?![^/]+$).)+/[^(.]+(?:\((?!OSX|Linux).+\))?\.sublime-settings
https://regex101.com/r/kgJMq4/2
(?!User) - Negative lookahead for User right after the first slash
(?:(?![^/]+$).)+ - Repeat any character that's not followed by non-slash characters and the end of the string
/[^(.]+ - Match the final slash, then repeat non-parentheses, non-dot characters, so as to check for an optional group:
(?:\((?!OSX|Linux).+\))? - Parentheses surrounding a phrase that does not start with OSX or Linux

Get tag name of the first question by using regex

I got a Problem with the following regex pattern:
m).*?^([^n]*)(modified)([^n]*)$.*
I want to replace the clipboard with
Clipboard := RegExReplace(Clipboard, "m).*?^([^n]*)(modified)([^n]*)$.*" ,"" )
Source looks like:
Ask Question Interesting 326 Featured
Hot Week Month 1 vote 0 answers 12 views
Type Guard for empty object
typescript modified 2 mins ago kremerd 312
0 votes
Expected result should be:
typescript modified 2 mins ago kremerd 312
But its replacing nothing. If this works i want to get later the tagnames ^([^n]*) by using regExMatch.
I am scripting with autohotkey (a windows open souce) from https://autohotkey.com
You want to match a line that contains a modified substring. The dot in a regex does not match the newline by default, so you need to pass the s (DOTALL) modifier (you may add it together with m, MULTILINE, modifier that makes ^ match the start of string position and $ to match the end of line position). Besides, to match non-newlines you need [^\n] (not [^n]).
To solve the issue you may use
RegExMatch(Clipboard, "s)^.*?(\n[^\n]*)(modified|asked|answered)", res)
Grab the whole line value via res, the text before the keywords via res1 and the keyword itself with res2.
Details
s) - the . now matches any char including line break chars
^ - start of the string
.*? - any 0+ chars, as few as possible
(\n[^\n]*) - Group 1 (accessed via res1 later): a newline followed with 0+ chars other than newline chars
(modified|asked|answered) - any of the three alternatives: modified, asked or answered.

Visual Basic - RegEx - Overall Length Check regardless the number of matches

I have the following problem :
This is my RegEx-Pattern :
\d*[a-z A-Z][a-zA-Z0-9 _?!()\/\\]*
It allows anything but numbers that stand alone like : 1 , 11 , 111 or so on.
My question : How can I set the overall Length of the input regardless of the matches ?
i tried it with several options like {1,30} before each match and i put the regex in a group with ( ) and then {1,30} but it still doesnt work.
If anyone could help me i would appreciate it :).
Allowed string:
Group1
Group 1
1Group
Group!?()\/
Group !()\?!
a1 a1 a1 a1
Not Allowed:
1
11
And so on. {1,30} after a match restricts the number of how many times i can input the match. What i want to know is: How can i set the maximum length of my above RegEx, like after 30 chars the input is reached regardless of the matches?
In order to disallow a numeric string input only, you can use a negative look-ahead (?!\d+$) and to set a limit to the input, use a limiting quantifier {1,30}:
(?!\d+$)[a-zA-Z0-9 _?!()\/\\]{1,30}
See demo
Note that if you plan to match whole strings, you'd need anchors: ^ at the beginning will anchor the regex to the beginning of string, and $ will anchor at the end.
^(?!\d+$)[a-zA-Z0-9 _?!()\/\\]{1,30}$
See another demo