2

我有一组从谷歌草图导出的坐标,带有我一直试图用正则表达式去除的额外绒毛。我认为将 3D 绘图从例如 SketchUp 快速获取到画布和 .xsi 文件中真的很有趣。是一个变量中的多个数据集实例:

$str = 'SI_NurbsCurve Edge1 {
        1、
        0,
        0,
        4、
        0,0,1,1,
        2、
        870.243,1229.35,143.395,1
        927.537,1323.53,103.842,1
        }

        SI_NurbsCurve Edge2 {
        1、
        0,
        0,
        4、
        0,0,1,1,
        2、
        899.54,1217.88,116.255,1
        870.243,1229.35,143.395,1
        }';

我尝试使用此正则表达式从多个实例中删除除坐标数据之外的所有内容:

$reg = '#SI_NurbsCurve 边[^"]* {
        1、
        0,
        0,
        4、
        0,0,1,1,
        2,#';  
$rep="";
$str=preg_replace($reg,$rep,$str);

但是,这只会回显在字符串中找到的最后一个坐标集,在此示例中仍保留以下内容:

899.54,1217.88,116.255,1
870.243,1229.35,143.395,1

除此之外,我试图去掉每行坐标上出现的最后一个数字“1”,所以整个例子最终看起来像这样:

870.243,1229.35,143.395,
927.537,1323.53,103.842,

899.54,1217.88,116.255,
870.243,1229.35,143.395,

我将非常感谢您的时间和专业知识!

4

3 回答 3

0

我认为您正在寻找 $str = substr($str,0,-1)

于 2012-08-07T13:17:16.030 回答
0

您的第一个问题(仅获取最后一个值)可​​能是由以下原因引起的:

#SI_NurbsCurve Edge[^"]*

您将需要一个非贪婪的正则表达式,或者如果后面的值Edge只是数字:

#SI_NurbsCurve Edge[0-9]*

之后,您可以截取剩余每一行的最后两个字符。

您可能还需要转义{字符:\{并在每组之后考虑}和空格/换行符,因此第一行应该类似于:

$str = '#(\}\s+)?SI_NurbsCurve Edge[0-9]* \{

请参阅Codepad上的工作示例(每行的最后 2 个字符除外...)。

为了摆脱,1每行末尾的剩余部分,您可以使用以下命令更改preg_replace行:

$str=preg_replace(array($reg, '#,1\r#'),array($rep,"\r"),$str);

这至少适用于键盘,但可能取决于换行符的编码。

于 2012-08-07T13:20:55.390 回答
0

无论如何,这不是一个完美的解决方案,但是,使用可用的测试数据,以下将返回所需的输出:

$str = 'SI_NurbsCurve Edge1 {
        1,
        0,
        0,
        4,
        0,0,1,1,
        2,
        870.243,1229.35,143.395,1
        927.537,1323.53,103.842,1
        }

        SI_NurbsCurve Edge2 {
        1,
        0,
        0,
        4,
        0,0,1,1,
        2,
        899.54,1217.88,116.255,1
        870.243,1229.35,143.395,1
        }';

function stripExtra( $inElem ){
  return !preg_match( '/^(?:(?:[0124](?:,0,1,1)?\,)|(?:\})|(?:SI_NurbsCurve Edge.+ \{))$/' , $inElem );
}

$arr2 = array_filter( array_map( 'trim' , explode( "\n" , preg_replace( "/\,1\s+\n/" , ",\n" , $str ) ) ) , 'stripExtra' );

var_dump( $arr2 );

# Returns
# array(5) {
#   [7]=>
#   string(25) "870.243,1229.35,143.395,"
#   [8]=>
#   string(25) "927.537,1323.53,103.842,"
#   [10]=>
#   string(0) ""
#   [18]=>
#   string(24) "899.54,1217.88,116.255,"
#   [19]=>
#   string(25) "870.243,1229.35,143.395,"
# }

遍历解决方案...

function stripExtra( $inElem ){
  return !preg_match( '/^(?:(?:[0124](?:,0,1,1)?\,)|(?:\})|(?:SI_NurbsCurve Edge.+ \{))$/' , $inElem );
}

此函数将匹配呈现的字符串。根据提供的字符串是否与特定模式匹配,它将返回 true 或 false。这将允许我们在稍后阶段删除不需要的行。此处使用的模式将匹配以下行:

SI_NurbsCurve Edge1 {
0,
1,
2,
4,
0,0,1,1,
}

注意:仅当这些行没有以一个或多个空格为前缀时,它才会匹配这些行。但是,由于您的最终输出已经剥离了所有空间,所以这没什么大不了的。

因此,为了可读性,我将在这里将我的单行奇迹转换为多行,以便更好地解释它。

$arr2 = preg_replace( "/1\s+\n/" , "\n" , $str );

这将根据要求仅用逗号替换行末尾的任何“,1”实例。

$arr2 = explode( "\n" , $arr2 );

这会根据换行符拆分字符串,创建一个数组,每行形成一个新元素。

$arr2 = array_map( 'trim' , $arr2 );

这使用array_map()函数 ( PHP Documentation ) 将trim()函数 ( PHP Documentation ) 应用于每个元素,从每个元素中删除任何前导和/或尾随空格。

$arr2 = array_filter( $arr2 , 'stripExtra' );

还记得我们上面写的那个函数吗?现在我们遍历数组,并测试每个元素。如果它们与上述行不匹配,则将它们保留在数组中。如果它们与上面不需要的行匹配,则从数组中删除该元素。

于 2012-08-07T13:50:58.167 回答