Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 用元素替换每个字符_Php_Regex_String_Replace_Preg Replace - Fatal编程技术网

Php 用元素替换每个字符

Php 用元素替换每个字符,php,regex,string,replace,preg-replace,Php,Regex,String,Replace,Preg Replace,这就是我所拥有的 $str = 'Just a <span class="green">little</span> -text åäö width 123#'; $str='就一点-文本宽度123'; 这就是我需要的 跨度和空间中的结果也可能是换行 $result = '<span></span><span></span><span></span><span></span>

这就是我所拥有的

$str = 'Just a <span class="green">little</span> -text åäö width 123#';
$str='就一点-文本宽度123';
这就是我需要的

跨度和空间中的结果也可能是换行

$result = '<span></span><span></span><span></span><span></span> <span></span> <span class="green"><span></span><span></span><span></span><span></span><span></span><span></span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span>';
$result='';
你可能想知道我为什么需要这个。我想构建一个东西,其中任何角色都由一个块表示。看起来有点像Windows XP上的碎片整理

问题

  • 将每个字符替换为
  • 不要触摸字符串中已经存在的HTML范围(可能很难?)。可以有多个HTML元素
  • 不要触摸空格和换行符
  • Regexp应该这样做吗?还是Xpath
到目前为止我做了什么?

我找到了关于regexp的文章,但没有替换每个字符(摘录空格和换行符)

$result=preg_replace(“/??/”,“,$str”);
打印(结果);

是否要求只使用一个正则表达式

如果不是,您可以用一些唯一的字符替换需要安全保护的子字符串,执行regexp替换,将子字符串替换为那个唯一的字符

就这样,

$str2 = str_replace('<span class="green">little</span>', '$', $str);
$str3 = preg_replace("/([^\s\n\$])/", "<span></span>", $str2);
$result = str_replace('$', '<span class="green">little</span>', $str3);
$str2=str\u replace('little','$','str');
$str3=preg_replace(“/([^\s\n\$])/”,“”,$str2);
$result=str_replace(“$”、“little”、$str3);
观看现场演示

UPD:

也许这只是一个暗示。我的建议是存储需要存储的子字符串,替换所有需要的内容,将存储的值放回字符串中

$str = 'Just a <span class="green">little</span> -text åäö width 123#';

preg_match_all('/<[^>]+>/', $str, $matches);
$storage=array();
for($i=0, $n=count($matches[0]); $i<$n; $i++)
{
    $key=str_repeat('$', $i+1);
    $value=$matches[0][$i];
    $storage[$key]=$value;
    $str=str_replace($value, $key, $str);
}
$storage=array_reverse($storage);

$str = preg_replace("/([^\s\n\$])/", "<span></span>", $str);
foreach($storage as $k=>$v)
{
    $str=str_replace($k, $v, $str);
}
echo htmlspecialchars($str);
$str='就一点-文本宽度123';
preg_match_all('/]+>/',$str,$matches);
$storage=array();
对于($i=0,$n=count($matches[0]);$i$v)
{
$str=str_替换($k,$v,$str);
}
echo htmlspecialchars($str);

工作演示在那里

虽然这可能是一个正则表达式,但我会使用循环。下面的示例代码适用于单字节字符集,但可以针对多字节(如UTF-16)或可变字节(如UTF-8)字符集进行修改

$input = 'Just a <span class="green">little</span> -text åäö width 123#';
$output = '';
$length = strlen($input);
$i = 0;
$matches = array(); // preg_match variable
// While for finer control
while($i < $length) {
    // Check for start of span tag, check for < character first for speed-up
    if($input[$i] == "<" && preg_match("#<span[^>]*>.*</span>#siU", substr($input, $i), $matches) == 1) {
        // Skip the span tag
        $i = $i + strlen($matches[0]);
        $output .= $matches[0];
    } else {
        $output .= "<span></span>";
        $i++;
    }
}
$input='就一点点-textåäöwidth 123#';
$output='';
$length=strlen($input);
$i=0;
$matches=array();//预匹配变量
//而对于更精细的控制
而($i<$length){
//检查跨度标签的起始位置,首先检查<字符是否加速
如果($input[$i]=“*#siU”,substr($input,$i),$MATCHS)==1){
//跳过span标记
$i=$i+strlen($matches[0]);
$output.=$matches[0];
}否则{
$output.=“”;
$i++;
}
}

有点像黑客,但试试这个:

$str="Just a <span class=\"green\">little</span> -text åäö\n width 123#";

// get all span tags
if(preg_match_all("/(\<span.*\<\/span\>)/", $str, $matches))
{
    // replace spans with #
    $str=preg_replace_all("/(\<span.*\<\/span\>)/", "#", $str);

    //print_r($matches);
}
// replace all non spaces, CR and #
$str=preg_replace("/[^\s\n#]/", "<span></span>", $str);
// replenish the matched spans
while(list($key,$value)=each($matches[0]))
{
    $str=preg_replace('/#/', $value, $str, 1);
}
$str=“只要一点-文本宽度123”;
//获取所有跨度标记

如果(preg_match_all(“/”(\),那么下面是我使用的方法:

$str='只要一点文字åäöwidth 123#aaa lol';
//这需要PHP5.3+
$output=preg#u replace_回调(“#.*?(]*>.*?)|.*is”,函数($m){
如果(!isset($m[1]){return preg_replace('/\S/','',$m[0]);}
$array=explode($m[1],$m[0]);
$array=preg_replace('/\S/',''$array);
返回(内爆($m[1],$array));
}美元/平方米);
回波(输出);
输出:

<span></span><span></span><span></span><span></span> <span></span> <span class="green">little</span><span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span>aaa</span> <span></span><span></span><span></span>
小aaa
您可以使用

$str='就一点-文本宽度123';
功能替换($matches){
if(strlen($matches[0])==1)
{
返回“”;
}
其他的
{
返回$matches[0];
}
}

$result=preg\u replace\u callback(“~不需要hacky regex解决方案。使用状态机的简单for循环应该可以:

define('STATE_READING', 1);
define('STATE_TAG', 2);

$str = 'Just a <span class="green">little</span> -text åäö width 123#';
$result = '';

$state = STATE_READING;
for($i = 0, $len = strlen($str); $i < $len; $i++) {
    $chr = $str[$i];

    if($chr == '<') {
        $state = STATE_TAG;
        $result .= $chr;
    } else if($chr == '>') {
        $state = STATE_READING;
        $result .= $chr;
    } else if($state == STATE_TAG || strlen(trim($chr)) === 0) {
        $result .= $chr;
    } else {
        $result .= '<span></span>';
    }
}
define('STATE_READING',1);
定义('STATE_TAG',2);
$str='就一点-文本宽度123';
$result='';
$state=状态读数;
对于($i=0,$len=strlen($str);$i<$len;$i++){
$chr=$str[$i];
如果($chr==''){
$state=状态读数;
$result.=$chr;
}如果($state==state|u TAG | strlen(trim($chr))==0,则为else{
$result.=$chr;
}否则{
$result.='';
}
}
如果我们正在读取一个标记或单个字符,这个循环只是跟踪。如果它是一个标记(或空白),则追加实际字符,否则追加

结果:

<span></span><span></span><span></span><span></span> <span></span> <span class="green"><span></span><span></span><span></span><span></span><span></span><span></span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span>

这不是一个老套的正则表达式方法。这是一个坚实、简洁、一行一个函数调用解决方案,它避免了在字符串中的每个字符上迭代一系列条件,保留了标记,并关心多字节字符

alexn的解决方案没有保持
åäö
的可见字符长度。他的解决方案将在屏幕上打印6个开始和结束跨距标记,而不仅仅是3个。这是因为没有使用
mbä
函数。在本主题中,请注意本页上任何不使用
mbä
前缀字符串函数的方法。

我建议的解决方案将利用
(*跳过)(*失败)
技术忽略/取消遇到的所有标记,然后只匹配字符串中的非空白字符

代码:()

$str='就一点-文本宽度123';
var_export(preg_replace('/]*>(*SKIP)(*FAIL)|\S/',''$str));//没有“u”标志表示åäö将是跨度x6
回音“\n”;
var_导出(preg_replace('/]*>(*跳过)(*失败)|\S/u',''$str));/“u”标志表示将跨越x3
输出:(向右滚动查看unicode标志对模式的影响)

“”
//请注意åäö->的替换数量----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------1111111111 2222222223333333333 44444444444 55555555555 66666666666
'      '
//请注意åäö->--------------------------------------------------------------------------------------------------------------------------
$str = 'Just a <span class="green">little</span> -text åäö width 123#';

function replacement($matches) {
            if (strlen($matches[0]) == 1) 
            {
                return "<span></span>";
            }
            else 
           {
               return $matches[0];
           }
}

$result = preg_replace_callback("~<span.*?<\s*/\s*span>|\S~", "replacement", $str);
print_r($result);
define('STATE_READING', 1);
define('STATE_TAG', 2);

$str = 'Just a <span class="green">little</span> -text åäö width 123#';
$result = '';

$state = STATE_READING;
for($i = 0, $len = strlen($str); $i < $len; $i++) {
    $chr = $str[$i];

    if($chr == '<') {
        $state = STATE_TAG;
        $result .= $chr;
    } else if($chr == '>') {
        $state = STATE_READING;
        $result .= $chr;
    } else if($state == STATE_TAG || strlen(trim($chr)) === 0) {
        $result .= $chr;
    } else {
        $result .= '<span></span>';
    }
}
<span></span><span></span><span></span><span></span> <span></span> <span class="green"><span></span><span></span><span></span><span></span><span></span><span></span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span>
$str = 'Just a <span class="green">little</span> -text åäö width 123#';
var_export(preg_replace('/<[^>]*>(*SKIP)(*FAIL)|\S/','<span></span>',$str));  // no "u" flag means åäö will be span x6
echo "\n";
var_export(preg_replace('/<[^>]*>(*SKIP)(*FAIL)|\S/u','<span></span>',$str)); // "u" flag means åäö will be span x3
'<span></span><span></span><span></span><span></span> <span></span> <span class="green"><span></span><span></span><span></span><span></span><span></span><span></span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span>'
// notice the number of replacements for åäö ->-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------111111111111122222222222223333333333333444444444444455555555555556666666666666
'<span></span><span></span><span></span><span></span> <span></span> <span class="green"><span></span><span></span><span></span><span></span><span></span><span></span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span> <span></span><span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span>'
// notice the number of replacements for åäö ->-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------111111111111122222222222223333333333333