هل يوجد محلل جيد وقابل لإعادة الاستخدام يحول السلسلة إلى تسلسل هرمي من القوائم؟

StackOverflow https://stackoverflow.com/questions/456259

سؤال

أود أن تأخذ سلسلة مثل هذا:

[One, Two[A, B[i, ii, iii, iv], C], Three]

وتحويلها إلى تسلسل هرمي للقوائم، بحيث إذا قمت بتنفيذ تعليمات برمجية مثل ما يلي:

Console.Write(myList[1][1][2]);

سيكون الإخراج:

iii

آمل أن يكون هذا مطلبًا شائعًا بما يكفي لوجود بعض أكواد التحليل البسيطة المكتوبة بلغة C#.

اسمحوا لي أن أعرف إذا كان من الممكن صياغة سؤالي بشكل أكثر وضوحا.

هل كانت مفيدة؟

المحلول

JSON وطرق ممتازة لتخزين مثل هذه الامور.

وكما قال سبنس - وهذا هو مشكلة صعبة - أنا لا أنصح المتداول بنفسك

.

وانتقل لأسفل إلى أسفل التي تصل JSON للتطبيقات في معظم اللغات.

نصائح أخرى

يجب أن أذهب مع التعبير العادي.يمكن أن تمنحك مطابقات السلسلة الفرعية والتعبيرات الفرعية التكرار للحصول على sub-sub-...مستويات في.

استخدم شيئًا مثل /^\[(.+)\]$/ في الإعداد المسبق لجمع مستوى واحد من العناصر.قم بمعالجتها حتى لا تتلقى مستوى بعد الآن، وانفجر في "،" بعد أن تحصل على الشجاعة لسلسلة واحدة.

تقسيم النتيجة بواسطة "،".

يجب أن يخرج مثل

  • [واحد، اثنان[أ، ب[i، ii، iii، iv]، C]، ثلاثة]
    • واحد
    • اثنين
    • [أ، ​​ب[ط، ثانيا، ثالثا، رابعا]، ج]
      • أ
      • ب
      • [الأول والثاني والثالث والرابع]
        • أنا
        • ثانيا
        • ثالثا
        • رابعا
      • ج
    • ثلاثة

أخيرًا، قم بقص المساحات اليسرى/اليمنى للحصول على نتيجة مصقولة.

هل لك بعد صفائف أو القوائم؟

وهذا من شأنه أن يكون من الصعب للغاية أن تفعل مع سلاسل لديك للتعامل مع مسافات، أو استخدام فاصلة في عنصر الخ.

إذا كان لديك السيطرة على ما هو في هذه القائمة، أقترح عليك أن تنظر في XML أو التسلسل ثنائي، التي لديها مكتبات لمساعدتك على القيام بذلك.

وانها ليست الإجابة العملية، ولكن إذا كنت قادرا على استخدام بيتا NET 4.0، يمكن أن ننظر إلى أوسلو (والأدوات اللاحقة) التي مايكروسوفت النامية من أجل نصية DSL، والتي على ما يبدو هو بالضبط ما تحتاجه.

وتصويتي هو أيضا لXML أو JSON أو شكل آخر إذا كان لديك القدرة على التحكم في الشكل. ولكنها تفتقر إلى ذلك، وهنا تنفيذ بيثون من محلل لأنني كنت بالملل.

class ExprParser(object):
current = []
list_stack = []

def __init__(self):
    pass

def parse(self,input):
    for atom in [s.strip() for s in input.split(',')]:
        self.parse_atom(atom)
    return self.current

def do_pushes(self,atom):
    """ Strip off the '[' and push new lists """
    i = 0
    while i < len(atom) and atom[i] == '[':
        self.push()
        i += 1
    return atom[i:]

def do_pops(self,atom):
    """ Pop the lists """
    i = 0
    while i < len(atom) and atom[i] == ']':
        self.pop()
        i += 1

def parse_atom(self,atom):
    push_start = atom.find('[')

    rest = self.do_pushes(atom[push_start:]) if push_start >= 0 else atom

    pop_start = rest.find(']')

    val = rest[:pop_start] if pop_start >= 0 else rest

    self.add(val)

    if pop_start >= 0:
        self.do_pops(rest[pop_start:])

def push(self):
    self.current = []
    self.list_stack.append(self.current)

def pop(self):
    done = self.list_stack.pop()
    self.current = self.list_stack[-1] if self.list_stack else done
    if self.current is not done:
        self.add(done)

def add(self,val):
    self.current.append(val)

استخدم مثل:

parser = ExprParser()
parser.parse('[One, Two[A, B[i, ii, iii, iv], C], Three]')

ولا يعالج ولو لإدخال تالف الخطأ.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top