【问题标题】:How can I parse this plaintext RP-style string into a more generic XML-style one?如何将此纯文本 RP 样式字符串解析为更通用的 XML 样式字符串?
【发布时间】:2015-06-30 10:39:18
【问题描述】:

我正在制作一个应用程序,它将角色扮演风格的消息翻译成更通用的东西。用户可以指定他们的偏好,例如:

Moves
 - /me <move>
 - *<move>*
Speech
 - <speech>
 - "<speech>"
Out-of-Character
 - [<ooc>]
 - ((ooc))
 - //ooc

我需要解析这样的消息:

/me eats food "This is *munch* good!" [You're good at this]

或者像这样:

*eats food* This is *munch* good! ((You're good at this))

变成一个更通用的、类似 XML 的字符串:

<move>eats food <speech>This is <move>munch</move> good!</speech> <ooc>You're good at this</ooc></move>

但是关于哪个在哪个里面。例如:

*eats food "This is munch* good" // You're good at this

应该被解析为:

<move>eats food "This is munch</move><speech> good" </speech><ooc> You're good at this</ooc>

即使那不是用户想要的。请注意,最后一个示例中的引号没有被解析,因为它们没有包装完整的段,并且当前移动段在遇到第一个时还没有完成,并且在第二个时语音已经开始,并且第二个在它之后没有另一个围绕一个单独的语音片段。

我尝试过迭代地、递归地、使用树甚至使用正则表达式来执行此操作,但我还没有找到像我想要的那样工作的解决方案。 如何将上述 RP 样式消息解析为上述通用 XML 样式消息?

同样重要的是保留间距。

以下是使用上述首选项的其他示例:

I like roller coasters.
[what are you like?]
/me eats a hamburger // wanna grab lunch after this?
*jumps up and down* This ((the party)) is great!
/me performs *an action* within an action "And that's just fine [As is *an action* in ooc in speech]"
And messages /me can change contexts // at any point
[But ill-formatted ones *must be parsed] according "to* the rules"
-And text formatted in <non-specified ways> is &not treated; specially-

变成:

<speech>I like roller coasters.</speech>
<ooc>what are you like?</ooc>
<move>eats a hamburger <ooc> wanna grab lunch after this?</ooc></move>
<move>jumps up and down</move><speech> This <ooc>the party</ooc> is great!</speech>
<move>performs <move>an action</move> within an action <speech>And that's just fine <ooc>As is <move>an action</move> in ooc in speech</ooc></speech></move>
<speech>And messages <move>can change contexts <ooc> at any point</ooc></move></speech>
<ooc>But ill-formatted ones *must be parsed</ooc><speech> according <speech>to* the rules</speech></speech>
<speech>-And text formatted in &lt;non-specified ways&gt; is &amp;not treated; specially-</speech>

【问题讨论】:

    标签: algorithm text-parsing string-parsing


    【解决方案1】:

    您拥有的是一堆应该触发 xml 标记的标记。使用每个标签的函数来实现这一点相当简单。

    void move(){
         xmlPrintWriter.println("<move>");
         parse();
         xmlPrintWriter.println(content);
         xmlPrintWriter.println("</move>");
    }
    

    parse() 在哪里消费和分类输入文本。

     void parse(){
         if (text.startsWith("*")) action = MOVE;
         ... other cases
    
         if ( action == MOVE){
             move();
         }
         ... other actions.
    

    parse 方法必须检查所有可能的状态改变者 "*" -> move, "((" -> ooc, """ -> speech 等等。

    这里MOVE是一个类常量,action是一个状态变量,还有textxmlPrintWritermoveparse 都是方法

    如果您允许最后一个示例,此方法将不起作用。然后情况变得非常棘手,需要根据具体情况来决定。

    【讨论】:

    • 那是 C 吗?抱歉,我应该指定我希望有一个更多与语言无关的解决方案,因为我将尝试为桌面(可能所有 Java)和手机(Android Java、iOS Swift 和 WP C#)制作本机客户端
    • @Supuhstar 我试图让它像伪。我将使用 Java 概念进行编辑。
    • 哦.. 我不应该三次给出相同的例子。并非所有都以&lt;move&gt; 开头。现在添加另一个示例。
    • 好的,我又添加了几个示例案例。希望他们有所帮助。
    • @Supuhstar 这个想法仍然有效。您将通过解析递归标签。语音似乎是文本默认值,从它开始解析。特殊的“规则”需要在每个功能中逐案处理。除了“特殊”情况,这是一个常规的解析器,网上的例子很多。 cogitolearning.co.uk/?p=523 似乎是一个合理的起点。
    【解决方案2】:

    可能会产生这种影响:

    public static RPMessageSegment split(RPMessageSegment text)
    {
        ArrayList<RPMessageSegment> majorSegments = new ArrayPP<>();
        scan: for(int i = 0, l = text.length() - 1; i < l; i++)
        {
            dels: for(Delimiter d : delimiters)
            {
                if (d.startsWith(text, i))
                {
                    RPMessageSegment newSegment = d.extractSegment(text, i);
                    i += newSegment.lengthWithOriginalDelimiters();
                    majorSegments.add(newSegment);
                    continue scan;
                }
            }
        }
    
        if (majorSegments.length() == 1)
            return majorSegments.get(0);
    
        for(int i = 0, l = majorSegments.length(); i < l; i++)
        {
            majorSegments.set(i, split(majorSegments.get(i)));
        }
        return new RPMessageSegment(majorSegments);
    }
    

    当然,这假定被引用的类具有这些响应预期的方法。它们应该不难想象,更不用说写了。

    在解析为RPMessageSegments 后,可以很容易地将其回显到由 XML 样式标签包围的字符串中

    【讨论】:

      猜你喜欢
      • 2016-06-12
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多