在括号

时间:2015-09-15 08:31:43

标签: c# regex string-comparison string-matching ordereddictionary

我有一个令牌类的后续字符列表:

3 ( 16 ) 23 ( 24 ( 40 ) 50 ( 66 ) 76 ) 83 ( 88 ( 104 ) 127 )

我的要求是在此列表中找到一对括号。在列表中,括号对是:3,16; 24,40; 50,66; 23,76; 88104; 83127

我正在尝试使用以下方法:

public static Dictionary<int,int> GetPair(List<Token> data)
{
     List<Token> token = data;
     var pair = new Dictionary<int, int>();

     int startIndex = -1;
     int currentPosition = -1;
     int finalIndex = -1;

     foreach (var item in token)
     {
         if (item.TokenValue == "(" && (currentPosition == -1 || currentPosition>startIndex) )
         {
             startIndex = item.TokenID;
             currentPosition = startIndex;
         }
         if (item.TokenValue == ")")
         {
             finalIndex = item.TokenID;
             currentPosition = finalIndex;
             pair.Add(startIndex, finalIndex);
         }               
     }   

     return pair;
}

public class Token
{
    public int TokenID { get; set; }
    public string TokenValue { get; set; }
}

我一直在寻找“23”的位置,因为列表中还有另一个左括号,它用“24(”代替它。请帮助我修改逻辑吗?

4 个答案:

答案 0 :(得分:3)

我没有测试过,但这应该可以解决问题:

public static Dictionary<int,int> GetPair(List<Token> data)
{
    var pair = new Dictionary<int, int>();

    var stack = new Stack<Token>();
    foreach (var item in token)
    {
        if (item.TokenValue == "(")
        {
            stack.Push(item);
            continue;
        }

        if (item.TokenValue == ")")
        {
            var starting = stack.Pop();
            pair.Add(starting.TokenId, item.TokenId);
        }
    }

    return pair;
}

答案 1 :(得分:1)

这是一个经典的访谈qustion,你用Stack解决它:

public static Dictionary<int,int> GetPair(List<Token> data)
{
    Stack<Token> stacken = new Stack<Token>();
    var pair = new Dictionary<int, int>();
    Token temp = new Token();

    foreach (char A in data)
    {
         if (item.TokenValue == "(" )
         {
              stacken.Push(A);
         }

         if (item.TokenValue == ")" )
         {
             if (stacken.Last() == '(')
             {
                  temp = stacken.Pop();
                  pair.Add(temp.TokenID,item.TokenID)
             }
             else
             {
                  stacken.Push(A);
             }
         }
    }

    return pair; 
}         

答案 2 :(得分:0)

您也可以使用正则表达式。可能它不像Vera rind解决方案那么快。

var i=$('table tr').length;

$(".addmore").on('click',function(){
    count=$('table tr').length;

    var data="<tr><td><input type='checkbox' class='case'/></td><td><span id='snum"+i+"'>"+count+".</span></td>";
    data +="<td><input class='form-control' type='text' id='countryname_"+i+"' name='countryname[]'/></td> <td><input class='form-control' type='text' id='country_no_"+i+"' name='country_no[]'/></td><td><input class='form-control' type='text' id='phone_code_"+i+"' name='phone_code[]'/></td><td><input class='form-control' type='text' id='country_code_"+i+"' name='country_code[]'/></td></tr>";
    $('table').append(data);
    row = i ;
    $('#countryname_'+i).autocomplete({
    source: function( request, response ) {
        $.ajax({
            url : "<?php echo base_url(); ?>admin/billing/get_country",
            dataType: "json",
            method: 'post',
            data: {
               name_startsWith: request.term,
               type: 'country_table',
               row_num : row
            },
             success: function( data ) {
                 response( $.map( data, function( item ) {
                    var code = item.split("|");
                    return {
                        label: code[0],
                        value: code[0],
                        data : item
                    }
                }));
            }
        });
    },
    autoFocus: true,            
    minLength: 0,
    select: function( event, ui ) {
        var names = ui.item.data.split("|");
        id_arr = $(this).attr('id');
        id = id_arr.split("_");                 
        $('#country_no_'+id[1]).val(names[1]);
        $('#phone_code_'+id[1]).val(names[2]);
        $('#country_code_'+id[1]).val(names[3]);
    }               
  });

答案 3 :(得分:0)

修改

感谢 Vera rind 建议,我还写了解决方案,为每个(嵌套级别)使用.NET正则表达式,使用正则表达式:

(?<first>\d+)(?=\s\(\s(?<second>\d+)\s\))|(?<first>\d+)\s(?=\(\s(?:(?:[^()]|(?<Open>\()|(?<Content-Open>\)))+(?(Open)(?!))\s(?<second>\d+)))

DEMO

它会捕获组firstsecond中的值对。正则表达式直接匹配对的第一个值,第二个值由正向前瞻的组捕获。它不是最有效的方法,只要正确匹配就更容易在正则表达式测试器中验证。

OLD ANSWER

在其他正则表达式中(据我所知),没有这种优雅的方式来匹配平衡的可重复结构,因此对于两级括号,此解决方案仍然有效。在这种情况下,确切的解决方案更好,但如果整个数据的格式相同(间距和最大两个级别的paratheses深度),也可以使用正则表达式:

(\d+)\s\(\s(\d+)\s\)|(\d+)(?=\s\(\s(?:\d+\s\(\s\d+\s\)\s)+(\d+))

DEMO

其中:

  • (\d+)\s\(\s(\d+)\s\) - 匹配简单案例:namber与以下内容 括号中的数字:n1 (n2),值在第1组和第1组中捕获2,
  • (\d+)(?=\s\(\s(?:\d+\s\(\s\d+\s\)\s)+(\d+)) - 匹配号码 以下嵌套括号中的最后一个孤独数字:n1 ( x1 (x2) y1 (y2) n2 ),值在第3组和第3组中捕获4,

然而它会变化列表顺序。