VB.Net匹配并替换字符串中多个重叠括号集的内容

时间:2011-06-05 19:08:15

标签: regex vb.net parsing

我正在使用vb.net来解析我自己的基本脚本语言,如下所示。我试图处理2种不同类型的嵌套括号有点困难。

Assuming name = Sam
Assuming timeFormat = hh:mm:ss
Assuming time() is a function that takes a format string but  
         has a default value and returns a string.


Hello [[name]], the time is [[time(hh:mm:ss)]].
Result: Hello Sam, the time is 19:54:32.

The full time is [[time()]].
Result: The full time is 05/06/2011 19:54:32.

The time in the format of your choice is [[time([[timeFormat]])]].
Result: The time in the format of your choice is 19:54:32.

理论上我可以完全改变脚本的语法,但我宁愿不这样做。它的设计是为了启用没有引号的字符串,因为它将包含在XML文件中,并且该上下文中的引号变得混乱,并且非常容易出现错误和可读性问题。如果失败了,我可以重新设计使用除引号之外的东西来标记字符串,但我宁愿使用这种方法。

最好,除非我不知道其他方式,否则我想使用正则表达式。我知道标准的正则表达式并不能真正做到这一点,但我相信这可以使用vb.net中的MatchEvaluators和某种基于递归的替换方式。然而,在最后一天左右,我无法理解它,可能是因为它非常困难,可能是因为我病了,或者可能是因为我很胖。

我的部分内容有以下正则表达式。

Detecting the parentheses: (\w*?)\((.*?)\)(?=[^\(+\)]*(\(|$))
Detecting the square brackets: \[\[(.*?)\]\](?=[^\[+\]]*(\[\[|$))

我真的很感激这方面的一些帮助,因为它暂时保留了我项目的其余部分。对不起,如果我喋喋不休或者没有提供足够的细节,这是我在这里的第一个问题。

2 个答案:

答案 0 :(得分:1)

这是一个小样本,可以帮助您迭代几个匹配/组/捕获。我意识到我正在发布C#代码,但你很容易将其转换为VB.Net

//these two may be passed in as parameters:
string tosearch;//the string you are searching through
string regex;//your pattern to match
//...
Match m;
CaptureCollection cc;
GroupCollection gc;

Regex r = new Regex(regex, RegexOptions.IgnoreCase);
m = r.Match(tosearch);
gc = m.Groups;
Debug.WriteLine("Number of groups found = " + gc.Count.ToString());

// Loop through each group.
for (int i = 0; i < gc.Count; i++)
{
  cc = gc[i].Captures;
  counter = cc.Count;
  int grpnum = i + 1;
  Debug.WriteLine("Scanning group: " + grpnum.ToString() );

  // Print number of captures in this group.
  Debug.WriteLine("  Captures count = " + counter.ToString());

  if (cc.Count >= 1)
  {
    foreach (Capture cap in cc)
    {
      Debug.WriteLine(string.format("  Capture found: {0}", cap.ToString()));
    }
  }
}

答案 1 :(得分:0)

这是我为此编写的代码的略微简化版本。感谢大家的帮助,对不起,我忘了发布这个。如果您有任何问题或任何问题,请随时提出。

Function processString(ByVal scriptString As String)
    ' Functions
    Dim pattern As String = "\[\[((\w+?)\((.*?)\))(?=[^\(+\)]*(\(|$))\]\]"
    scriptString = Regex.Replace(scriptString, pattern, New MatchEvaluator(Function(match) processFunction(match)))

    ' Variables
    pattern = "\[\[([A-Za-z0-9+_]+)\]\]"
    scriptString = Regex.Replace(scriptString, pattern, New MatchEvaluator(Function(match) processVariable(match)))
    Return scriptString
End Function

Function processFunction(ByVal match As Match)
    Dim nameString As String = match.Groups(2).Value
    Dim paramString As String = match.Groups(3).Value
    paramString = processString(paramString)
    Select Case nameString
        Case "time"
            Return getLocalValueTime(paramString)
        Case "math"
            Return getLocalValueMath(paramString)
    End Select
    Return ""
End Function

Function processVariable(ByVal match As Match)
    Try
        Return moduleDictionary("properties")("vars")(match.Groups(1).Value)
    Catch ex As Exception
    End Try
End Function