0

Given a template that looks like this:

<td class="creditapp heading">{*}Street Address:</td>
<td colspan=2 class="tdaddressblock">
<!-- @template="addressBlock" for="buyer" prev="" @-->
     ^^ might be a space here, might not        ^^ always a space here
</td>

I need to read the name=value pairs out of the comment, plus the whole string so it can be replaced. Names could be any alpha-numeric with no spaces, values could contain anything except double quotes, will be short as possible, and will always be surrounded by double-quotes.

So, possible formats:

<!-- @pizza="yes" @-->
<!-- @ingredients="cheese sauce meat" @-->
<!-- @ drinks="yes, please" breadsticks="garlic, butter (lots); cheese" @-->

I've tried a dozen different variations, but the most successful I've been so far is to get the first name="value" pair and nothing else, or I get the whole page worth of stuff. So the desired matches are

[1] <!-- @ drinks="yes, please" breadsticks="garlic, butter (lots); cheese" @-->
[2] drinks
[3] yes, please
[4] breadsticks
[5] garlic, butter (lots); cheese

The closest I've come so far is

<!-- @(( |)([\w]+)="(.*?)")+ @-->

but it only returns the last pair, not all of them.

Bill in Kansas City
  • 360
  • 1
  • 5
  • 21
  • You can't do it this way. It's a 2 step process. Within a replace callback, match the entire comment ``. Each match grabs the content, do another regex on the content. `\b(\w+)\s*=\s*"([^"]*)"`, do any manipulation, then write the content back to the original replacement. If you're using Dot-Net, use a delegate for the callback. If not, you need to construct the new string yourself within a while loop. –  Jul 19 '17 at 21:14
  • Note that if you are not replacing, AND using Dot-Net regex, you can use a _Capture Collection_ to get everything in a single match. Example: `` where the key val pairs are the group 1 and group 2 array[index] (respectively). –  Jul 19 '17 at 21:24

1 Answers1

0

Implementation of the 2 step processes @sln mentioned in VBScript:

Option Explicit

Dim rCmt : Set rCmt = New RegExp
rCmt.Global = True
rCmt.Pattern = "<!-- @[\s\S]+?@-->"
Dim rKVP : Set rKVP = New RegExp
rKVP.Global = True
rKVP.Pattern = "(\w+)=""([^""]*)"""
Dim sInp : sInp = Join(Array( _
    "<td class=""creditapp heading"">{*}Street Address:</td>" _
  , "<td colspan=2 class=""tdaddressblock"">" _
  , "<!-- @template=""addressBlock"" for=""buyer"" prev="""" @-->" _
 , "</td>" _
 , "<!-- @ pipapo=""i dont care""" _
 , "rof=""abracadabra"" prev="""" @-->" _
), vbCrLf)

WScript.Echo sInp
WScript.Echo "-----------------"
WScript.Echo rCmt.Replace(sInp, GetRef("fnRepl"))
WScript.Quit 0

Function fnRepl(sMatch, nPos, sSrc)
  Dim d : Set d = CreateObject("Scripting.Dictionary")
  Dim ms : Set ms = rKVP.Execute(sMatch)
  Dim m
  For Each m In ms
      d(m.SubMatches(0)) = m.SubMatches(1)
  Next
  fnRepl = "a comment containing " & Join(d.Keys)
End Function

output:

cscript 45200777-2.vbs
<td class="creditapp heading">{*}Street Address:</td>
<td colspan=2 class="tdaddressblock">
<!-- @template="addressBlock" for="buyer" prev="" @-->
</td>
<!-- @ pipapo="i dont care"
rof="abracadabra" prev="" @-->
-----------------
<td class="creditapp heading">{*}Street Address:</td>
<td colspan=2 class="tdaddressblock">
a comment containing template for prev
</td>
a comment containing pipapo rof prev

As Mr. Gates Doc for the .Replace method sucks, see 1, 2, 3.

Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96