Regex'ing code functions - multiline?

  • Thread starter Thread starter Masa Ito
  • Start date Start date
M

Masa Ito

I am trying to capture the contents of a function with Regex. I am using
Expresso to test (nice - thanks for the great tool UltraPico!). I can
handle my own with single line regex's (I think).. I want to have a
named capture of the entire 'contents' of specific functions.
EG: Sample code
<Description("{0} is a required field.")> _
Protected Overridable Function AccountIDRequired(ByVal target As
Object, ByVal e As RuleArgs) As Boolean
Return mAccountID.ToString.Length > 0
End Function

I know the function name, and can easily match the first line:
Protected\sOverridable\sFunction\sAccountIDRequired.*

But the .* doesn't capture the newlines (/n). I want to capture
everything up to the End Function, so figured I could do something like:
(Protected\sOverridable\sFunction\sAccountIDRequired.*End\sFunction)

If I know that it is always 3 lines (like the example) I could do:
Protected\sOverridable\sFunction\sAccountIDRequired.*\n.*\n.*

this matches my test perfectly, but I need it to match as many lines as
necessary until the End Function.

Can anyone help?

TIA!
 
Hvis du bruger dotnet kan du bruge RegexOptions.Multiline, jf:

Regex.Match(inputstreng, regex, RegexOptions.Multiline)


- ellers (?m:), fx:


(?m:etregulærtudtryk)


Vh. Morten
 
But the .* doesn't capture the newlines (/n). I want to capture

Use (.|\n)*
(Protected\sOverridable\sFunction\sAccountIDRequired.*End\sFunction)
this matches my test perfectly, but I need it to match as many lines as
necessary until the End Function.

Try something like:
(Protected\sOverridable\sFunction\sAccountIDRequired(.|\n)*End\sFunction)

Remember that this regex doesn't match if the function is defined like
(split lines with _):
Protected Overridable _
Function AccountIDRequired(ByVal target As Object, ByVal e As RuleArgs)
As Boolean

If you need to parse the method inside VS, I would use VS automation
(macro or add-in). Create following two macros and call test() macro.
This will do what you want:
Sub test()
Dim ce As CodeElement
For Each ce In
DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElements
traverse(ce)
Next
End Sub

Sub traverse(ByVal ce As CodeElement)
If ce.Kind = vsCMElement.vsCMElementFunction Then
If ce.Name = "AccountIDRequired" Then
Dim cme As CodeFunction = CType(ce, CodeFunction)

MsgBox(cme.StartPoint.CreateEditPoint.GetText(cme.EndPoint.CreateEditPoint))
' use properties of cme to investigate the method further
End If
ElseIf ce.IsCodeType Then
Dim tce As CodeType = CType(ce, CodeType)
Dim subCe As CodeElement
For Each subCe In tce.Members
traverse(subCe)
Next
End If
End Sub

See http://www.helixoft.com/blog/archives/6 how to create macro.
<Description("{0} is a required field.")> _
Protected Overridable Function AccountIDRequired(ByVal target As

Just out of curiosity, what do you use <Description> attribute at method
for? It has practical meaning only for properties and assemblies.
Properties with <Description> attribute will show this description in
Properties window. Not methods. To have IntelliSense tooltips and Object
browser description, you need to use XML comments (<summary>, <param>,
etc.) instead, see http://tinyurl.com/ywtomx

Regards
 
Use (.|\n)*


Try something like:
(Protected\sOverridable\sFunction\sAccountIDRequired(.|\n)*End\sFunctio
n)

Interesting - thanks - I will give this a try. I haven't seen that
syntax before. I actually noticed the 'single line' option description
in Expresso describes it as 'make . match \n as well as any other
character' - which is exactly what I had wanted. For some reason, I had
thought the opposite - that Singleline would not match line breaks - go
figure!?
Remember that this regex doesn't match if the function is defined like
(split lines with _):
Protected Overridable _
Function AccountIDRequired(ByVal target As Object, ByVal e As
RuleArgs) As Boolean

If you need to parse the method inside VS, I would use VS automation
(macro or add-in). Create following two macros and call test() macro.
This will do what you want:
Sub test()
Dim ce As CodeElement
For Each ce In
DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElements
traverse(ce)
Next
End Sub

Sub traverse(ByVal ce As CodeElement)
If ce.Kind = vsCMElement.vsCMElementFunction Then
If ce.Name = "AccountIDRequired" Then
Dim cme As CodeFunction = CType(ce, CodeFunction)

MsgBox(cme.StartPoint.CreateEditPoint.GetText(cme.EndPoint.CreateEditPo
int))
' use properties of cme to investigate the method
further
End If
ElseIf ce.IsCodeType Then
Dim tce As CodeType = CType(ce, CodeType)
Dim subCe As CodeElement
For Each subCe In tce.Members
traverse(subCe)
Next
End If
End Sub
See http://www.helixoft.com/blog/archives/6 how to create macro.

That is a great idea - for some reason I hadn't even thought about
macros/programming in vs.

I ended up getting my code to do work great - I am upgrading a very large
CSLA based app from 1.5 to 2.1, and this section of code updated
thousands of validation rules for me ... :)

Just out of curiosity, what do you use <Description> attribute at
method for? It has practical meaning only for properties and
assemblies. Properties with <Description> attribute will show this
description in Properties window. Not methods. To have IntelliSense
tooltips and Object browser description, you need to use XML comments
(<summary>, <param>, etc.) instead, see http://tinyurl.com/ywtomx

This is used in the validation/error text - when a rule is broken this
text is displayed to the end user in the UI.

Thanks a ton for your help and ideas!

Masa
 
Back
Top