在调车场之前处理逗号分隔列表

发布于 2024-11-03 14:35:12 字数 633 浏览 0 评论 0原文

因此,我使用 Shunting-Yard 算法处理 XML 字符串中的一些数学运算。诀窍是我想允许通过使用逗号分隔列表生成随机值。例如...

( ( 3 + 4 ) * 12 ) * ( 2, 3, 4, 5 ) )

我已经有了一个基本的调车场处理器。但我想在处理表达式之前预处理字符串以从列表中随机选择一个值。这样我最终可能会得到:

( ( 3 + 4 ) * 12 ) * 4 )

就我的理解而言,调车场的设置已经相当复杂,所以我犹豫是否尝试改变它来处理这个问题。通过错误检查来处理这个问题听起来像是一场噩梦。因此,我认为事先寻找该模式是否有意义?我正在考虑使用正则表达式,但我不是“那些”人中的一员...尽管我希望我是...虽然我发现了一些 示例,我不确定如何修改它们以首先检查括号?我也不相信这将是最好的解决方案。

附带说明一下,如果解决方案是正则表达式,它也应该能够匹配逗号列表中的字符串(仅字符,无符号),因为我将在 Shunting-Yard 实现中处理值的特定字符串。

提前感谢您的想法。

So I'm processing some math from XML strings using the Shunting-Yard algorithm. The trick is that I want to allow the generation of random values by using comma separated lists. For example...

( ( 3 + 4 ) * 12 ) * ( 2, 3, 4, 5 ) )

I've already got a basic Shunting-Yard processor working. But I want to pre-process the string to randomly pick one of the values from the list before processing the expression. Such that I might end up with:

( ( 3 + 4 ) * 12 ) * 4 )

The Shunting-Yard setup is already pretty complicated, as far as my understanding is concerned, so I'm hesitant to try to alter it to handle this. Handling that with error checking sounds like a nightmare. As such, I'm assuming it would make sense to look for that pattern beforehand? I was considering using a regular expression, but I'm not one of "those" people... though I wish that I was... and while I've found some examples, I'm not sure how I might modify them to check for the parenthesis first? I'm also not confident that this would be the best solution.

As a side note, if the solution is regex, it should be able to match strings (just characters, no symbols) in the comma list as well, as I'll be processing for specific strings for values in my Shunting-Yard implementation.

Thanks for your thoughts in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚风撩人 2024-11-10 14:35:12

使用两个正则表达式可以轻松解决此问题。应用于整个文本的第一个正则表达式与每个括号内的逗号分隔值列表相匹配。应用于每个先前匹配的列表的第二个正则表达式匹配列表中的每个值。下面是一个 PHP 脚本,其函数在给定具有多个列表的输入文本的情况下,将每个列表替换为随机选择的值之一:

<?php // test.php 20110425_0900

function substitute_random_value($text) {
    $re = '/
        # Match parenthesized list of comma separated words.
        \(           # Opening delimiter.
        \s*          # Optional whitespace.
        \w+          # required first value.
        (?:          # Group for additional values.
          \s* , \s*  # Values separated by a comma, ws
          \w+        # Next value.
        )+           # One or more additional values.
        \s*          # Optional whitespace.
        \)           # Closing delimiter.
        /x';
    // Match each parenthesized list and replace with one of the values.
    $text = preg_replace_callback($re, '_srv_callback', $text);
    return $text;
}
function _srv_callback($matches_paren) {
    // Grab all word options in parenthesized list into $matches.
    $count = preg_match_all('/\w+/', $matches_paren[0], $matches);
    // Randomly pick one of the matches and return it.
    return $matches[0][rand(0, $count - 1)];
}

// Read input text
$data_in = file_get_contents('testdata.txt');

// Process text multiple times to verify random replacements.
$data_out  = "Run 1:\n". substitute_random_value($data_in);
$data_out .= "Run 2:\n". substitute_random_value($data_in);
$data_out .= "Run 3:\n". substitute_random_value($data_in);

// Write output text
file_put_contents('testdata_out.txt', $data_out);

?>

substitute_random_value() 函数调用 PHP preg_replace_callback() 函数,它将每个列表匹配并替换为列表中的值之一。它调用 _srv_callback() 函数,该函数随机挑选一个值并将其作为替换值返回。

给定此输入测试数据 (testdata.txt):

( ( 3 + 4 ) * 12 ) * ( 2, 3, 4, 5 ) )
( ( 3 + 4 ) * 12 ) * ( 12, 13) )
( ( 3 + 4 ) * 12 ) * ( 22, 23, 24) )
( ( 3 + 4 ) * 12 ) * ( 32, 33, 34, 35 ) )

以下是脚本运行一个示例的输出:

Run 1:< br>
( ( 3 + 4 ) * 12 ) * 5 )
( ( 3 + 4 ) * 12 ) * 13 )
( ( 3 + 4 ) * 12 ) * 22 )
( ( 3 + 4 ) * 12 ) * 35 )
运行2:
( ( 3 + 4 ) * 12 ) * 3 )
( ( 3 + 4 ) * 12 ) * 12 )
( ( 3 + 4 ) * 12 ) * 22 )
( ( 3 + 4 ) * 12 ) * 33 )
运行3:
( ( 3 + 4 ) * 12 ) * 3 )
( ( 3 + 4 ) * 12 ) * 12 )
( ( 3 + 4 ) * 12 ) * 23 )
( ( 3 + 4 ) * 12 ) * 32 )

请注意,此解决方案使用 \w+ 来匹配由“word”字符组成的值,即 [A-Za-z0 -9_]。如果这不满足您的要求,可以轻松更改。

编辑:以下是 substitute_random_value() 函数的 Javascript 版本:

function substitute_random_value(text) {
    // Replace each parenthesized list with one of the values.
    return text.replace(/\(\s*\w+(?:\s*,\s*\w+)+\s*\)/g,
        function (m0) {
           // Capture all word values in parenthesized list into values.
            var values = m0.match(/\w+/g);
            // Randomly pick one of the matches and return it.
            return values[Math.floor(Math.random() * values.length)];
        });
}

This is easily solved using two regexes. The first regex, applied to the overall text, matches each parenthesized list of comma separated values. The second regex, applied to each of the previously matched lists, matches each of the values in the list. Here is a PHP script with a function that, given an input text having multiple lists, replaces each list with one of its values randomly chosen:

<?php // test.php 20110425_0900

function substitute_random_value($text) {
    $re = '/
        # Match parenthesized list of comma separated words.
        \(           # Opening delimiter.
        \s*          # Optional whitespace.
        \w+          # required first value.
        (?:          # Group for additional values.
          \s* , \s*  # Values separated by a comma, ws
          \w+        # Next value.
        )+           # One or more additional values.
        \s*          # Optional whitespace.
        \)           # Closing delimiter.
        /x';
    // Match each parenthesized list and replace with one of the values.
    $text = preg_replace_callback($re, '_srv_callback', $text);
    return $text;
}
function _srv_callback($matches_paren) {
    // Grab all word options in parenthesized list into $matches.
    $count = preg_match_all('/\w+/', $matches_paren[0], $matches);
    // Randomly pick one of the matches and return it.
    return $matches[0][rand(0, $count - 1)];
}

// Read input text
$data_in = file_get_contents('testdata.txt');

// Process text multiple times to verify random replacements.
$data_out  = "Run 1:\n". substitute_random_value($data_in);
$data_out .= "Run 2:\n". substitute_random_value($data_in);
$data_out .= "Run 3:\n". substitute_random_value($data_in);

// Write output text
file_put_contents('testdata_out.txt', $data_out);

?>

The substitute_random_value() function calls the PHP preg_replace_callback() function, which matches and replaces each list with one of the values in the list. It calls the _srv_callback() function which randomly picks out one of the values and returns it as the replacement value.

Given this input test data (testdata.txt):

( ( 3 + 4 ) * 12 ) * ( 2, 3, 4, 5 ) )
( ( 3 + 4 ) * 12 ) * ( 12, 13) )
( ( 3 + 4 ) * 12 ) * ( 22, 23, 24) )
( ( 3 + 4 ) * 12 ) * ( 32, 33, 34, 35 ) )

Here is the output from one example run of the script:

Run 1:
( ( 3 + 4 ) * 12 ) * 5 )
( ( 3 + 4 ) * 12 ) * 13 )
( ( 3 + 4 ) * 12 ) * 22 )
( ( 3 + 4 ) * 12 ) * 35 )
Run 2:
( ( 3 + 4 ) * 12 ) * 3 )
( ( 3 + 4 ) * 12 ) * 12 )
( ( 3 + 4 ) * 12 ) * 22 )
( ( 3 + 4 ) * 12 ) * 33 )
Run 3:
( ( 3 + 4 ) * 12 ) * 3 )
( ( 3 + 4 ) * 12 ) * 12 )
( ( 3 + 4 ) * 12 ) * 23 )
( ( 3 + 4 ) * 12 ) * 32 )

Note that this solution uses \w+ to match values consisting of "word" characters, i.e. [A-Za-z0-9_]. This can be easily changed if this does not meet your requirements.

Edit: Here is a Javascript version of the substitute_random_value() function:

function substitute_random_value(text) {
    // Replace each parenthesized list with one of the values.
    return text.replace(/\(\s*\w+(?:\s*,\s*\w+)+\s*\)/g,
        function (m0) {
           // Capture all word values in parenthesized list into values.
            var values = m0.match(/\w+/g);
            // Randomly pick one of the matches and return it.
            return values[Math.floor(Math.random() * values.length)];
        });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文