Php 如何计算标记内部文本中的字数,并根据字数将其与标记分开

Php 如何计算标记内部文本中的字数,并根据字数将其与标记分开,php,regex,Php,Regex,我有这样一个问题: 下面是一个示例,但您必须对其进行调整,以适应单词中允许的字符: <?php $input = 'i am a <b>software</b> <span style=\"color:red;\">engineer.</span> i work at a company.'; $pattern = '#((?: \s* (<[^>]*>)* [a-z.-]+ (</[^>]*>)* ){

我有这样一个问题:


下面是一个示例,但您必须对其进行调整,以适应单词中允许的字符:

<?php
$input = 'i am a <b>software</b> <span style=\"color:red;\">engineer.</span>  i work at a company.';
$pattern = '#((?: \s* (<[^>]*>)* [a-z.-]+ (</[^>]*>)* ){0,5}).*#x';
$result = preg_replace($pattern, '$1', $input);
var_dump($result);

这是可能的。您可以像这样使用preg_match_:

<?php
$input = 'i am a <b>software</b> <span style=\"color:red;\">engineer. And </span> i work at a company.';
$pattern = '#(
\s*
(<[^>]*>)*
[a-z.-]+
(</[^>]*>)*
)#x';
preg_match_all($pattern, $input, $matches);
var_dump($matches);
然后,对于每个匹配项,测试$matches[2][index]是否为空,以及$matches[3][index]是否为空,以添加结束标记。 但我认为它不完整,而且容易出错。您可能需要对其进行修改,以使其能够在所有可能的情况下运行。

更精确的解决方案

<?php
$input = 'i am a <b>software</b> <span style=\"color:red;\">engineer. And </span> i work at a company.';

var_dump(customParse($input, 5));
var_dump(customParse($input, 4));
var_dump(customParse($input, 3));

$input = 'i am a <b>software</b> <foo style=\"color:red;\">engineer. And </foo> i work at a company.';

var_dump(customParse($input, 5));

function customParse($input, $limit) {
    $pattern = '#(
    \s*
    (?: <(\w+) [^>]* >)*
    [a-z.-]+
    (</[^>]*>)*
    )#x';
    preg_match_all($pattern, $input, $matches);
    $result = '';
    for ($nbMatch = 0; $nbMatch < $limit; $nbMatch++) {
        $capturedText = $matches[0][$nbMatch];
        $openTag = $matches[2][$nbMatch];
        $closeTag = $matches[3][$nbMatch];

        $result .= $capturedText;

        if ($openTag && !$closeTag) {
            $result .= '</' . $openTag . '>';
        }
    }

    return $result;
}

谢谢。但这有可能吗?如果$in=我是一名软件工程师。我在一家公司工作$我是一名软件工程师。字数5,并加上结束标记,请给我明确的答案,就像你的第一个答案。你的第一个答案很好。。我认为必须使用匹配子模式。但我不能理解匹配子模式。请修改第一个答案。我希望那会奏效哇,太好了。它工作得很好。非常感谢我的荣幸:再一次,你必须使用[a-z.-]+来匹配你真正可以接受的词。我可以做到,我对正则表达式有一些了解。但这个案子对我来说是个先期标签。谢谢,我能得到你的FBID吗?StackOverflow是我的facebook;谢谢你的帮助。对于case-single标记会产生一个小问题,如:,
<?php
$input = 'i am a <b>software</b> <span style=\"color:red;\">engineer.</span>  i work at a company.';
$pattern = '#((?: \s* (<[^>]*>)* [a-z.-]+ (</[^>]*>)* ){0,5}).*#x';
$result = preg_replace($pattern, '$1', $input);
var_dump($result);
<?php
$input = 'i am a <b>software</b> <span style=\"color:red;\">engineer. And </span> i work at a company.';
$pattern = '#(
\s*
(<[^>]*>)*
[a-z.-]+
(</[^>]*>)*
)#x';
preg_match_all($pattern, $input, $matches);
var_dump($matches);
<?php
$input = 'i am a <b>software</b> <span style=\"color:red;\">engineer. And </span> i work at a company.';

var_dump(customParse($input, 5));
var_dump(customParse($input, 4));
var_dump(customParse($input, 3));

$input = 'i am a <b>software</b> <foo style=\"color:red;\">engineer. And </foo> i work at a company.';

var_dump(customParse($input, 5));

function customParse($input, $limit) {
    $pattern = '#(
    \s*
    (?: <(\w+) [^>]* >)*
    [a-z.-]+
    (</[^>]*>)*
    )#x';
    preg_match_all($pattern, $input, $matches);
    $result = '';
    for ($nbMatch = 0; $nbMatch < $limit; $nbMatch++) {
        $capturedText = $matches[0][$nbMatch];
        $openTag = $matches[2][$nbMatch];
        $closeTag = $matches[3][$nbMatch];

        $result .= $capturedText;

        if ($openTag && !$closeTag) {
            $result .= '</' . $openTag . '>';
        }
    }

    return $result;
}