How can I write a condition which will compare Recipient.AdressEntry for example with the following String "I351" using RegEx?
Here is my If condition which works but is hardcoded to every known email address.
For Each recip In recips
If recip.AddressEntry = "Dov John, I351" Then
objMsg.To = "example#mail.domain"
objMsg.CC = recip.Address
objMsg.Subject = Msg.Subject
objMsg.Body = Msg.Body
objMsg.Send
End If
Next
The reason I need this condition is email may have one of several colleagues from my team and one or more from another team. AdressEntry of my colleagues ends with I351 so I will check if this email contains one of my teammates.
For Each recip In recips
If (recip.AddressEntry = "Dov John, I351" _
Or recip.AddressEntry = "Vod Nohj, I351") Then
objMsg.To = "example#mail.domain"
objMsg.CC = recip.Address
objMsg.Subject = Msg.Subject
objMsg.Body = Msg.Body
objMsg.Send
End If
Next
You still didn't clarify exactly what the condition you want to use for matching is, so I'll do my best:
If you simply want to check if the string ends with "I351", you don't need regex, you can use something like the following:
If recip.AddressEntry Like "*I351" Then
' ...
End If
If you want to check if the string follows this format "LastName FirstName, I351", you can achieve that using Regex by using something like the following:
Dim regEx As New RegExp
regEx.Pattern = "^\w+\s\w+,\sI351$"
If regEx.Test(recip.AddressEntry) Then
' ...
End If
Explanation of the regex pattern:
' ^ Asserts position at the start of the string.
' \w Matches any word character.
' + Matches between one and unlimited times.
' \s Matches a whitespace character.
' \w+ Same as above.
' , Matches the character `,` literally.
' \s Matches a whitespace character.
' I351 Matches the string `I351` literally.
' $ Asserts position at the end of the string.
Try it online.
Hope that helps.
Related
colleagues.
I'm stuck on a simple question:
I have the connection string: Server=35.237.131.8,14333; Database=Online LIMS; Trusted_Connection = No; User Id = LimsUser; Password = lims42; Pooling=False; MultipleActiveResultSets=False; DRIVER = SQL SERVER; LastSection = false
And I want to delete the section DRIVER. It's very simple, but there is one issue: this section can be at the end of the string: "Server=35.237.131.8,14333; Database=Online LIMS; Trusted_Connection = No; User Id = LimsUser; Password = lims42; Pooling=False; MultipleActiveResultSets=False; DRIVER = SQL SERVER" and delimiter ';' is missing in this case.
My current regex (?<DriverSection>DRIVER.*?;*)(?=;|$) match the section at the end of the string and in the middle, but in the middle it does not include the separator ';', so this character is keeping in the string after deletion: Server=35.237.131.8,14333; Database=Online LIMS; Trusted_Connection = No; User Id = LimsUser; Password = lims42; Pooling=False; MultipleActiveResultSets=False;; LastSection = false
And I have two ';' characters in the string, what is wrong.
So my question: is it possible to match both cases by one regex?
My current regex is available here: https://regex101.com/r/OSZKtA/1
Thanks everybody.
check this out
(?<DriverSection>DRIVER.*?;*)(?<=;|$)
https://regex101.com/r/2CG6iw/1
You can use a match with a negated character class, and then optionally match the trailing ;
\b(?<DriverSection>DRIVER\s*=[^;]*;?)
\b A word boundary to prevent a partial word match
(?<DriverSection> Named group DriverSection
DRIVER\s*= Match DRIVER, optional whitespace chars and then =
[^;]* Match 1+ chars optional chars other than ;
;? Optionally match ;
) Close the named group
See a regex demo.
Match non-semicolons, which naturally stop at end of string anyway:
(?<=DRIVER = )[^;]+
See live demo.
(?<=DRIVER = ) is a look behind, meaning the previous characters must be "DRIVER = "
[^;] is a negated character class and means any character except a semicolon
+ means one or more
If your language/tool (not stated in question) does not support look arounds, you can still use the "non-semicolon" approach if you match the variable name too:
DRIVER = [^;]+
See live demo.
Given string:
some_function(inputId = "select_something"),
(...)
some_other_function(inputId = "some_other_label")
I would like to arrive at:
some_function(inputId = ns("select_something")),
(...)
some_other_function(inputId = ns("some_other_label"))
The key change here is the element ns( ... ) that surrounds the string available in the "" after the inputId
Regex
So far, I have came up with this regex:
:%substitute/\(inputId\s=\s\)\(\"[a-zA-Z]"\)/\1ns(/2/cgI
However, when deployed, it produces an error:
E488: Trailing characters
A simpler version of that regex works, the syntax:
:%substitute/\(inputId\s=\s\)/\1ns(/cgI
would correctly inser ns( after finding inputId = and create string
some_other_function(inputId = ns("some_other_label")
Challenge
I'm struggling to match the remaining part of the string, ex. "select_something") and return it as:
"select_something")).
You have many problems with your regex.
[a-zA-Z] will only match one letter. Presumably you want to match everything up to the next ", so you'll need a \+ and you'll also need to match underscores too. I would recommend \w\+. Unless more than [a-zA-Z_] might be in the string, in which case I would do .\{-}.
You have a /2 instead of \2. This is why you're getting E488.
I would do this:
:%s/\(inputId = \)\(".\{-}\)"/\1ns(\2)/cgI
Or use the start match atom: (that is, \zs)
:%s/inputId = \zs\".\{-}"/ns(&)/cgI
You can use a negated character class "[^"]*" to match a quoted string:
%s/\(inputId\s*=\s*\)\("[^"]*"\)/\1ns(\2)/g
So i want to match all strings of the form with a regex
(word1|word2|word3)/some/more/text/..unlimited parts.../more
so it starts with specific word and it does not end with /
examples to match:
word1/ok/ready
word2/hello
word3/ok/ok/ok/ready
What i want in the end is when i have a text with above 3 examples in it (spread around in a random text), that i receive an array with those 3 matches after doing regex.exec(text);
Anybody an idea how to start?
Thanks!
Something like this should work:
^(word1|word2|word3)(/\w+)+$
If you're using this in an environment where you need to delimit the regex with slashes, then you'll need to escape the inner slash:
/^(word1|word2|word3)(\/\w+)+$/
Edit
If you don't want to capture the second part, make it a non-capturing group:
/^(word1|word2|word3)(?:\/\w+)+$/
^^ Add those two characters
I think this is what you want, but who knows:
var input = '';
input += 'here is a potential match word1/ok/ready that is followed by another ';
input += 'one word2/hello and finally the last one word3/ok/ok/ok/ready';
var regex = /(word1|word2|word3)(\/\w+)+/g;
var results = []
while ((result = regex.exec(input)) !== null) {
results.push(result[0].split('/'));
}
console.log(results);
I am trying to write a VBA macro for MS Word 2010 that capitalizes letters after a special character. In my case an underscore "_". The words that I want to revise, start with a special prefix. I am having trouble with the replace operation. I am using Microsoft Regular Expression Library 5.5.
This is what I have so far:
Sub ReplaceFunc()
'
' ReplaceFunc Macro
'
'
Debug.Print ("entered replaceFunc")
Dim myRegex As New RegExp
myRegex.Global = True
myRegex.IgnoreCase = False
myRegex.MultiLine = True
' i want to find all words in the document which start with BlaBlub and have a suffix like _foo_bar or _foo_bar_foo
' e.g. BlaBlub_foo_bar, BlaBlub_foo_foo_bar_bar, BlaBlub_foo_bar_foo
myRegex.Pattern = "\bBlaBlub(_([a-z])+)+\b"
' works i get the results i was looking for
Set Matches = myRegex.Execute(ActiveDocument.Range.Text)
' now i want to capitalize every letter after a "_", e.g. BlaBlub_foo_bar --> BlaBlub_Foo_Bar
For Each Match In Matches
' The idea is to run a new RegEx on every found substring but this time with replace
Dim mySubRegex As New RegExp
mySubRegex.Global = True
mySubRegex.IgnoreCase = False
mySubRegex.MultiLine = True
' Matching every underscore followed by a non capital letter
mySubRegex.Pattern = "_([a-z])"
' getting start and endindex from the match to run the regex only on the found word
startIndex = Match.FirstIndex
endIndex = (Match.FirstIndex + Match.Length)
' where it fails with a syntax error
mySubRegex.Replace(ActiveDocument.Range(Start:=startIndex, End:=endIndex).Text , "_\u$1")
Next
Debug.Print ("leaving replaceFunc")
End Sub
The VBA macro fails with a syntax error in the line:
mySubRegex.Replace(ActiveDocument.Range(Start:=startIndex, End:=endIndex).Text , "_\u$1")
I am out of ideas, what to do to get it working. Can you point out what my error is and how to fix it?
This is very easy to correct, just suppress parentheses:
mySubRegex.Replace(ActiveDocument.Range(Start:=startIndex, End:=endIndex).Text , "_\u$1")
=>
mySubRegex.Replace ActiveDocument.Range(Start:=startIndex, End:=endIndex).Text , "_\u$1"
Or
Dim varVal
varVal = mySubRegex.Replace(ActiveDocument.Range(Start:=startIndex, End:=endIndex).Text , "_\u$1")
I was trying to remove all comments and empty lines in a file with the help of a macro. Now I came up with this solution which deletes the comments(there is some bug described below) but is not able to delete the blank lines in between -
Sub CleanCode()
Dim regexComment As String = "(REM [\d\D]*?[\r\n])|(?<SL>\'[\d\D]*?[\r\n])"
Dim regexBlank As String = "^[\s|\t]*$\n"
Dim replace As String = ""
Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection
Dim editPoint As EnvDTE.EditPoint
selection.StartOfDocument()
selection.EndOfDocument(True)
DTE.UndoContext.Open("Custom regex replace")
Try
Dim content As String = selection.Text
Dim resultComment As String = System.Text.RegularExpressions.Regex.Replace(content, regexComment, replace)
Dim resultBlank As String = System.Text.RegularExpressions.Regex.Replace(resultComment, regexBlank, replace)
selection.Delete()
selection.Collapse()
Dim ed As EditPoint = selection.TopPoint.CreateEditPoint()
ed.Insert(resultBlank)
Catch ex As Exception
DTE.StatusBar.Text = "Regex Find/Replace could not complete"
Finally
DTE.UndoContext.Close()
DTE.StatusBar.Text = "Regex Find/Replace complete"
End Try
End Sub
So, here is what it should looks like before and after running the macro.
BEFORE
Public Class Class1
Public Sub New()
''asdasdas
Dim a As String = "" ''asdasd
''' asd ad asd
End Sub
Public Sub New(ByVal strg As String)
Dim a As String = ""
End Sub
End Class
AFTER
Public Class Class1
Public Sub New()
Dim a As String = ""
End Sub
Public Sub New(ByVal strg As String)
Dim a As String = ""
End Sub
End Class
There are mainly two main problems with the macro
It cannot delete the blank lines in between.
If there is a piece of code which goes like this
Dim a as String = "Name='Soham'"
Then After running the macro it becomes
Dim a as String = "Name='"
To get rid of a line that contains whitespace or nothing, you can use this regex:
(?m)^[ \t]*[\r\n]+
Your regex, ^[\s|\t]*$\n would work if you specified Multiline mode ((?m)), but it's still incorrect. For one thing, the | matches a literal |; there's no need to specify "or" in a character class. For another, \s matches any whitespace character, including TAB (\t), carriage-return (\r), and linefeed (\n), making it needlessly redundant and inefficient. For example, at the first blank line (after the end of the first Sub), the ^[\s|\t]* will initially try to match everything before the word Public, then it will back off to the end of the previous line, where the $\n can match.
But a blank line, in addition to being empty or containing only horizontal whitespace (spaces or TABs), may also contain a comment. I choose to treat these "comment-only" lines as blank lines because it's relatively easy to do, and it simplifies the task of matching comments in non-blank lines, which is much harder. Here's my regex:
^[ \t]*(?:(?:REM|')[^\r\n]*)?[\r\n]+
After consuming any leading horizontal whitespace, if I see a REM or ' signifying a comment, I consume that and everything after it until the next line separator. Notice that the only thing that's required to be present is the line separator itself. Also notice the absence of the end anchor, $. It's never necessary to use that when you're explicitly matching the line separators, and in this case it would break the regex. In Multiline mode, $ matches only before a linefeed (\n), not before a carriage-return (\r). (This behavior of the .NET flavor is incorrect and rather surprising, given Microsoft's longstanding preference for \r\n as a line separator.)
Matching the remaining comments is a fundamentally different task. As you've discovered, simply searching for REM or ' is no good because you might find it in a string literal, where it does not signify the start of a comment. What you have to do is start from the beginning of the line, consuming and capturing anything that's not the beginning of a comment or a string literal. If you find a double-quote, go ahead and consume the string literal. If you find a REM or ', stop capturing and go ahead and consume the rest of the line. Then you replace the whole line with just the captured portion--i.e., everything before the comment. Here's the regex:
(?mn)^(?<line>[^\r\n"R']*(("[^"]*"|(?!REM)R)[^\r\n"R']*)*)(REM|')[^\r\n]*
Or, more readably:
(?mn) # Multiline and ExplicitCapture modes
^ # beginning of line
(?<line> # capture in group "line"
[^\r\n"R']* # any number of "safe" characters
(
(
"[^"]*" # a string literal
|
(?!REM)R # 'R' if it's not the beginning of 'REM'
)
[^\r\n"R']* # more "safe" characters
)*
) # stop capturing
(?:REM|') # a comment sigil
[^\r\n]* # consume the rest of the line
The replacement string would be "${line}". Some other notes:
Notice that this regex does not end with [\r\n]+ to consume the line separator, like the "blank lines" regex does.
It doesn't end with $ either, for the same reason as before. The [^\r\n]* will greedily consume everything before the line separator, so the anchor isn't needed.
The only thing that's required to be present is the REM or '; we don't bother matching any line that doesn't contain a comment.
ExplicitCapture mode means I can use (...) instead of (?:...) for all the groups I don't want to capture, but the named group, (?<line>...), still works.
Gnarly as it is, this regex would be a lot worse if VB supported multiline comments, or if its string literals supported backslash escapes.
I don't do VB, but here's a demo in C#.
I've just checked with the two examples from above, '+{.+}$ should do. Optionally, you could go with ('|'')+{.+}$ but the first solution also replaces the xml-descriptions ).
''' <summary>
''' Method Description
''' </summary>
''' <remarks></remarks>
Sub Main()
''first comment
Dim a As String = "" 'second comment
End Sub
Edit: if you use ('+{.+}$|^$\n) it deletes a) all comments and b) all empty lines. However, if you have a comment and a End Sub/Function following, it takes it up one line which results in a compiler error.
Before
''' <summary>
'''
''' </summary>
''' <remarks></remarks>
Sub Main()
''first comment
Dim a As String = "" 'second comment
End Sub
''' <summary>
'''
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function asdf() As String
Return "" ' returns nothing
End Function
After
Sub Main()
Dim a As String = ""
End Sub
Public Function asdf() As String
Return ""
End Function
Edit: To delete any empty lines Search Replace the following regex ^$\n with empty.
Delete the comments first using this regex
'+\s*(\W|\w).+
'+ - one or more ' for the beginning of each comment.
\s* - if there are spaces after the comment.
(\W|\w).+ - anything that follows except for line terminators.
Then remove the blank lines left using the regex Mr. Alan Moore provided.