我使用php在rtf格式文件中合并文本服务器端。
我的字段由文件不同部分中的一系列波浪号标识。
每个序列的长度不同。
为了使用substr_replace
用合并材料替换字段,我需要计算渐变序列的长度。
我可以使用以下方法找到第一个没有问题的代字号:
$firsttilde=strpos($filedata,'~',$currentposinfile);
其中(在此代码中)$filedata
是包含文件内容的字符串,$currentposinfile
是我搜索的起点。
我的问题是我找不到一个可以计算序列中相同字符数的函数。
从我看到的$filedata
的第一个代号看起来像这样(换句话说是一系列代字号):
' ~~~~~~~~~~'
我已经尝试strrpos
找到最后一个代字号,但这是在$filedata
的后面部分找到包含波浪号的字段。
我想要做的就是从字符串中我知道的位置计算波浪号的数量,但我找不到任何函数来执行此操作。
但必须有一个。
答案 0 :(得分:0)
您可以将preg_match_all
与PREG_OFFSET_CAPTURE
标志结合使用。这将保存在匹配变量中找到字符串的偏移量,允许您同时找到字符串及其偏移量。
$matches = Array();
preg_match_all( '/~+/', $input, $matches, PREG_OFFSET_CAPTURE);
foreach( $matches[0] as $k => $v ) {
$length = strlen( $v[0] );
echo "Found a string \"{$v[0]}\" beginning at {$v[1]} with length {$length}<br>";
}
对于下面的示例文本
$input = <<<TEXT
this is
~~~~~~~~
quite something
~~~~
TEXT;
输出将是:
Found a string "~~~~~~~~" beginning at 8 with length 8
Found a string "~~~~" beginning at 34 with length 4
答案 1 :(得分:0)
这使用for迭代来检查文本中的字符。 它是preg_match()解决方案的替代方案,它更紧凑。
<?php
$text = <<<'TEXT'
abc
~~~
def
~~~~~~
123
~~~~~~~~~~
TEXT;
//$currentposinfile = 0;
//$firsttilde = strpos($text,'~',$currentposinfile);
//$text = substr($text, $firsttilde);
$sequenceStarted = false;
$sequenceLength = 0;
$textLength = strlen($text);
for ($i = 0; $i <= $textLength; $i++) {
$char = $text[$i];
//echo 'Char ' . $char . ' at ' . $i . PHP_EOL;
if($char === '~') {
// found start of a sequence
if($sequenceStarted === false) {
$sequenceLength++;
$sequenceStarted = true;
$sequenceStartPosition = $i;
}
// it's a char in sequence
continue;
}
// found first char out of sequence
if($char !== '~' && $sequenceStarted === true) {
$sequenceStarted = false;
$sequenceEndPostion = $i - 1;
$sequenceLength = $i - $sequenceStartPosition;
echo 'Found a sequence of length: ' . $sequenceLength . ' starting at '.$sequenceStartPosition.' ending at ' . $sequenceEndPostion . '.' . PHP_EOL;
#break;
$sequenceLength = 0; $sequenceEndPostion = 0;
}
}
结果:
Found a sequence of length: 3 starting at 5 ending at 7.
Found a sequence of length: 6 starting at 15 ending at 20.
Found a sequence of length: 10 starting at 28 ending at 37.
如果您已经拥有序列块,则可以使用count_chars()。
<?php
$text = 'ABC~~~123';
$data = count_chars($text, 1);
echo 'The string "'. $text .'" contains the char "~" '. $data[126] . ' times.';
$ data [126] =使用ASCII码126表示〜
结果:字符串“ABC ~~~ 123”包含char“〜”3次。
答案 2 :(得分:0)
以下函数将遍历字符串并返回匹配数组:
function findSequences($str)
{
$ret = array();
$len = strlen($str);
$count = 0;
for($i = 0; $i <= $len; $i ++)
{
$char = @$str[$i] ?: null;
if($char == '~')
{
$count ++;
}
elseif($count > 0)
{
// Found end of sequence
$ret[] = array(
'start' => $i - $count,
'end' => $i - 1,
'len' => $count
);
$count = 0;
}
}
return $ret;
}
使用示例:
print_r(findSequences('~ABC~~~123~~'));
将输出一个包含找到的匹配项详细信息的数组:
Array
(
[0] => Array
(
[start] => 0
[end] => 0
[len] => 1
)
[1] => Array
(
[start] => 4
[end] => 6
[len] => 3
)
[2] => Array
(
[start] => 10
[end] => 11
[len] => 2
)
)
答案 3 :(得分:0)
感谢大家的回答 他们鼓励我尝试更难找到一个简单的解决方案。
我想出了这个: -
$lasttilde=$firsttilde;
while ($filedata[$lasttilde]=='~') { $lasttilde++; }
然后$filedata
特定部分的代字号数量是$lasttilde
和$firsttilde
之间的差异