php截取一段文字的前一百个字的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php截取一段文字的前一百个字的问题相关的知识,希望对你有一定的参考价值。

我想用php截取一段文字,这段文字里有汉字和字母,但有时候刚还截取汉字的一半。
怎么避免?

一般英文字符占一个字节,汉字占两个字节,有这么一种思路,在截取字符串的时候逐个判断要截取的字符是汉字还是英文字符,这样就不会出现错误了,下边给你帖一个我写的程序,你自己看下
<html>
<head>
<title>无标题文档</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

<body>
<?php
function msubstr($str,$start,$len)


?>
<form action="" name="myform" method="post">
输入字符串:<input type="text" name="str" value="5555我爱My祖国" /><br />
输入起始位置:<input type="text" name="str_start" /><br />
输入截取长度:<input type="text" name="str_len" /><br />
<input type="submit" name="sub" value="开始截取字符串" />
</form>
<?php
/*截取字符串的函数--------------数组式截取*/
function msubstr2($str,$start,$len)
$t = explode(" ",microtime());
$tt = round($t[0],5);
//将字符串中每个字符分开 并放到数组中
$str_arr = array();
$j = 1;
for($i=0;$i<strlen($str);$i++)
if(ord(substr($str,$i,1))>0xa0) //说明是汉字 则需要一次截取3个字符
$str_arr[$j] = substr($str,$i,3);
$i = $i+2;
else
$str_arr[$j] = substr($str,$i,1);

$j++;

print_r($str_arr);
for($i=$start;$i<=$len+$start-1;$i++)
if($i>count($str_arr)) //判断是否超出数组最大长度 如果是 则结束循环
break;

$str_temp .= $str_arr[$i];

$t = explode(" ",microtime());
$ttt = round($t[0],5);
return $ttt-$tt;
//return $str_temp;

function msubstr1($str,$start,$len)
$t = explode(" ",microtime());
$tt = round($t[0],5);
$j = 0; //记录截取的字符串的字符位置
$s = 0; //记录已经截取的字符长度
$str_temp = "";//记录截取的字符串
$k = strlen($str);
for($i=0;$i<$k;)//循环全部字
if($s>=$len) break;//如果已经截取的字符串长度超过要截取的长度 跳出循环 返回结果
if(ord(substr($str,$i,1))>0xa0) //判断是否为汉字
if($j+1>=$start)//如果当前截取字符位置大于等于要截取的字符串的开始位置并且当前已经截取的字符长度还没有超出要截取的字符串的长度 则将此字符为要截取的字符
$str_temp .= substr($str,$i,3);
$s++;//已经截取的字符串长度加1

$j++;//当前截取的字符串的位置加1
$i+=3;//确定为汉字 在utf8编码下占三个英文字符的长度 则需要记录三个字符
else
if($j+1>=$start)
$str_temp .= substr($str,$i,1); //截取英文字符
$s++;//已经截取的字符串长度加1

$j++;//当前截取的字符串的位置加1
$i++;//非汉字字符占一个字符的长度


$t = explode(" ",microtime());
$ttt = round($t[0],5);
//return $ttt-$tt;
return $str_temp;

if($_POST[sub])
echo msubstr1($_POST[str],$_POST[str_start],$_POST[str_len]);

?>
</body>
</html>
参考技术A 用php的
string mb_substr ( string $str , int $start [, int $length [, string $encoding ]] )

前提是php要安装 mb扩展
参考技术B mb_substr($string,0,100)

Project Euler 80: Square root digital expansion

众所周知如果一个整数的平方根不是一个整数,那么这个平方根就是一个无理数,这种平方根的小数表示是无限不循环的。二的平方根是(1.41421356237309504880...),它的前一百位数字的和是475。对于前一百个自然数,如果它的平方根是无理数,求这些无理数的小数表示的前一百之和的和。

分析:计算平方根的方法有很多,如经典的牛顿迭代法,但这些方法都会使用浮点数,从而容易出现近似误差的问题,在求小数表示的数位之和时容易出现错误。经过查阅资料,在这篇论文中我发现一个非常简单易懂的计算任意精度的平方根的方法,这种方法虽然收敛速度要慢于牛顿迭代法,但最大的优点是只需要通过整数的加减就可以得到答案,从而完全避免浮点误差问题。对算法的具体介绍和背后的原理大家可以参见论文,我这里只简单描述以下算法的实现步骤:

  • 要求非完全平方数(n)的平方根前(p)位有效数字之和,则设(a=5n,b=5)
    • 如果(age b),则(a-b ightarrow a,b+10 ightarrow b)
    • 如果(a<b),则(100a ightarrow a),并在(b)的个位数加上零构成一个新数再赋值给(b)
    • 如上一直循环,直到(b)的位数达到(p)位(实际中为了避免误差,会再多求两三位);
  • 循环结束后返回(b)的前(p)位数数位之和,即为题目所求。

对于前一百个自然数中的非完全平方数,依次求其小数表示的前一百个有效数字之和,然后把这些和加总起来,即为题目所求,代码如下:

# time cost = 42.1 ms ± 549 μs

def jarvis_sqrt_sum(n,prec=100):
    a,b = 5*n,5
    while len(str(b)) <= prec+3:
        if a >= b:
            a,b = a-b,b+10
        else:
            a,b = a*100,(b-b%10)*10+b%10
    return sum([int(x) for x in str(b)[:prec]])

def main():
    numbers = set(range(2,100))-{x**2 for x in range(2,10)}
    ans = 0
    for i in numbers:
        ans += jarvis_sqrt_sum(i)
    return ans

以上是关于php截取一段文字的前一百个字的问题的主要内容,如果未能解决你的问题,请参考以下文章

Project Euler 80: Square root digital expansion

python读取一个单元格内的前几个字的颜色

php要截取一段汉语文字,怎样才能保证不把汉字拆开?

用mysql查询出字段中的前几个字

小技巧CSS文字两端对齐

sqlmap