所以我使用Shunting-Yard算法处理XML字符串中的一些数学运算。诀窍在于,我想通过使用逗号分隔的列表来生成随机值。例如…
( ( 3 + 4 ) * 12 ) * ( 2, 3, 4, 5 ) )
我已经有一个基本的分流场处理器工作。但是我想预处理字符串,在处理表达式之前从列表中随机选择一个值。这样我可能会以:
结束( ( 3 + 4 ) * 12 ) * 4 )
分流场设置已经相当复杂,就我的理解而言,所以我很犹豫,试图改变它来处理这个。用错误检查来处理这个问题听起来像是一场噩梦。因此,我假设事先寻找这种模式是有意义的?我正在考虑使用正则表达式,但我不是"那些"人之一……虽然我希望我是……虽然我找到了一些例子,但我不确定如何修改它们以首先检查括号?我也不相信这是最好的解决方案。
作为旁注,如果解决方案是正则表达式,它应该能够匹配逗号列表中的字符串(只是字符,没有符号),因为我将在我的分流场实现中处理特定字符串的值。
提前感谢您的关心
这很容易用两个正则表达式解决。第一个正则表达式应用于整个文本,匹配每个用括号括起来的逗号分隔值列表。第二个正则表达式应用于之前匹配的每个列表,匹配列表中的每个值。下面是一个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:
( ( 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 )
注意,此解决方案使用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)];
});
}