Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using a regular expression to validate FQDN...

Status
Not open for further replies.

Joespower

IS-IT--Management
Jul 3, 2007
7
US
Okay guys, this is my first post, but I've used info from these forums in the past and you guys kick ass!

Here is my question:

I have a logon script that maps drives and printers, and I want make certain that the passed server references are FQDNs. So, I need a way to take a string and see if its a FQDN based on these rules:

1) The whole string can't be more than 255 characters.
2) Individual labels can't be more than 63 characters. (labels are the stuff between the ".'s")
3) Each label must begin with a letter.
4) Each label must end with a letter or number
5) The letters in between in a label can be numbers, letters, or hyphens (no underscores).
6) Case doesn't matter.
7) Can't contain any whitespace.
8) Can be no trailing "." at the end of the whole string (this is debatable, but its what we do internally).

Now I'm no newbie to regular expressions. I have used them a bunch when scripting in a Unix environment. But, I'm having a hard time with the vbscript syntax. I decided to start with the label portion of the RegExp, and what I have so far works as long as the label has more than 1 letter. Having a single letter label is valid for FQDNs, so I have to find a way to fix this...

So, I set up my RegExp like this:

Dim regExp
Set regExp = New RegExp
With regExp
.Pattern = "(((^[a-zA-Z])([a-zA-Z0-9]|-)*)+)(\w$){1,63}"
.IgnoreCase = True
.Global = True
End With


I then use the Test method to test out my passed server name. As I said, everything is fine until I reduce it to a single letter name, but then it breaks down...

Any help would be great!
 
[tt]'let s be the fqdn reference string under scrutiny
Dim s As String
Dim bFQDN As Boolean
Dim rx As RegExp
Dim a As Variant

[green]s="asdfadsfj-aldfk.qwersdfkj.kajdsfkjasd" 'otherwise provisioned for[/green]
a = Split(s, ".")

bFQDN = (Len(s) < 256) And (Len(a(UBound(a))) <> 0)

If bFQDN Then
Set rx = New RegExp
With rx
'.ignorecase = True
.Pattern = "^[a-zA-Z]([a-zA-Z0-9\-]{0,61}[a-zA-Z]|[a-zA-Z]?)$"
End With

For i = 0 To UBound(a)
bFQDN = bFQDN And rx.test(a(i))
If Not bFQDN Then Exit For
Next
End If

Debug.Print bFQDN 'the desired boolean result here
[/tt]
 
Hey, thanks tsuji!

This works to check the labels, but it does not go so far as to check if the entire string is a valid FQDN. For instance it doesn't check to see if there are at least 3 labels (like "a.b.c" ... while "a" is a valid label, it is not an FQDN by itself). I guess if the "a" variable is an array of all of the labels, you could take a count of items in the array, and if its 3 or better its an FQDN...

Anyway, this is a good start. I'll keep working on it and post my finished product here. This is a totally different approach then what I was taking since was trying to match the entire thing in one pass. This makes the regular expression easier and more readable...

Thanks again tsuji...
 
Okay, I've been working on this code for a little while and trying to integrate it into my program. But, I have some problems. Read the coments for clarification:

Code:
Function TestFQDN(this_server)
	Wscript.Echo "TestFQDN Called!"
	
	' this_server is the server name portion of a UNC
	'   path sent to a subroutine that calls this function
	
	Dim bFQDN
	Dim rx
	Dim a
	
	a = Split(this_server, ".")
	Wscript.Echo TypeName(a)
	' for some reason, this returns "variant" instead of 
	'  "object" for an array.
	
	bFQDN = (Len(this_server) < 256) And (Len(a(UBound(a))) <> 0)
	' this gives me a type mismatch because Len() is a 
	'  string function being used on what should be an array.
	' I don't understand the use of Ubound() either...
	
	If bFQDN Then
	    Set rx = New RegExp
	    With rx
	        .ignorecase = True
	        .Pattern = "^[a-zA-Z]([a-zA-Z0-9\-]{0,61}[a-zA-Z]|[a-zA-Z]?)$"    
	    End With
	
	    For i = 0 To UBound(a)  ' again, why UBound() ??
	        bFQDN = bFQDN And rx.test(a(i))
	        If Not bFQDN Then Exit For
	    Next
	End If

	If bFQDN AND (a.Length > 2) Then
	' this is what I was saying in my former post.
	' I need to make sure there are at least 3 array 
	'  elements for a FQDN.
	
		Wscript.Echo "Passed!"
	Else
		Wscript.Echo "Failed!"
	End IF
	
	TestFQDN = bFQDN
End Function

Again, any help here would be great! When I get all this done, I'll post the logon script here for everyone to use...
 
I tested this and it seems to work for both values of "s" (see code). The original code is from tsuji which I modified slightly.

Code:
Public Sub FQDN_Test()

         ' A test for FQDN.
         '*********************************
         ' From Tek-Tips VB forum tsuji.
         '*********************************
         
         'let s be the fqdn reference string under scrutiny
'         s = "asdfadsfj-aldfk.qwersdfkj.kajdsfkjasd"  'otherwise provisioned for
         s = "[URL unfurl="true"]www-2.mysite.here.com."[/URL]                 ' My FQDN with trailing "."
         
         a = Split(s, ".")
         
         '****************************
         ' My additions
         '****************************
         If ((Not (a)) = -1) Then
            Debug.Print "Illegal FQDN, host not present"
            bFQDN = False
         Else
            bFQDN = (Len(s) < 256) And (UBound(a) >= 2) ' Added uBound >= 2.
            If (Len(a(UBound(a))) > 0) Then
               ' FQDN does not end in "."
               LastElement = UBound(a)
            Else
               ' FQDN does end in "." which is legal.
               LastElement = UBound(a) - 1
            End If
         End If
         
         If bFQDN Then
             Set rx = New RegExp
             With rx
                 '.ignorecase = True
                 .Pattern = "^[a-zA-Z]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]|[a-zA-Z0-9]?)$"
             End With
         
             For i = 0 To LastElement
                 bFQDN = bFQDN And rx.Test(a(i))
                 If Not bFQDN Then Exit For
             Next
         End If
         
         Debug.Print bFQDN    'the desired boolean result here

End Sub

From my research the FQDN can end with a "." This is reflected in my code. Let me know if that assumption is incorrect.


HyperEngineer
If it ain't broke, it probably needs improvement.
 
I tried to run this code without alteration. It fails. I get a "Type Mismatch" error on this line:

Code:
If ((Not (a)) = -1) Then

This is the same error I was struggling with using tsuji's code...
 
Well, this is another reason to use option explicit. As has been said many times here, it's pretty much de rigeur that one should use it.

I also got this error until I added the following to the code:
Code:
Dim s As String
Dim a() As String
Dim bFQDN As Boolean
Dim LastElement As Integer
Dim rx As RegExp
Dim i As Integer
What I get from this is that when a is a variant array you run into type mismatch problems. If you specifically dim a() as a variant you will get a type mismatch when attempting to apply the split function, as you no doubt found in tsuji's code.

HTH

Bob
 
Joe,

Bob is right. I did explicitly dim the variables as he has them listed. You have to dim a() as string. It won't work if dim as a variant. My oversight not to include the Dim statements. I pulled it out of my code in a testing ground project and forgot the Dim statements.
Thanks Bob.




HyperEngineer
If it ain't broke, it probably needs improvement.
 
<I pulled it out of my code in a testing ground project and forgot the Dim statements.

I had the feeling it was something like that. :)
 
Hey guys, thanks for the help...

Actually, I think I'm posting this in the wrong forum. I'm using VBSCRIPT, not VB for applications.

I noticed because I can't use the "As" statement like the code above (I get an "Exspected End of Statement" error).

So, I guess I'm going to repost this stuff in the right forum...

If you want, I could come back here later and post what the results turn out to be...

Thanks again... Joey
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top