Для случая, когда вы будете делать это на больших строках (или даже непосредственно из файла), explode()
- не лучший способ сделать это. Представьте, сколько памяти будет потрачено впустую, если вам придется разделить строку размером 2 МБ в памяти.
С небольшим количеством кода и (при условии PHP >= 5.0
) вы можете легко реализовать класс PHP Iterator
, который будет делать именно это. Это будет близко к генератору в Python и вкратце, вот код:
/**
* Class for CONTINOUS reading of words from string.
*/
class WordsIterator implements Iterator {
private $pos = 0;
private $str = '';
private $index = 0;
private $current = null;
// Regexp explained:
// ([^\\w]*?) - Eat everything non-word before actual word characters
// Mostly used only if string beings with non-word char
// ([\\w]+) - Word
// ([^\\w]+?|$) - Trailing thrash
private $re = '~([^\\w]*?)([\\w]+)([^\\w]+?|$)~imsS';
// Primary initialize string
public function __construct($str) {
$this->str = $str;
}
// Restart indexing
function rewind() {
$this->pos = 0;
$this->index = 0;
$this->current = null;
}
// Fetches current word
function current() {
return $this->current;
}
// Return id of word you are currently at (you can use offset too)
function key() {
return $this->index;
}
// Here's where the magic is done
function next() {
if( $this->pos < 0){
return;
}
$match = array();
++$this->index;
// If we can't find any another piece that matches... Set pos to -1
// and stop function
if( !preg_match( $this->re, $this->str, $match, 0, $this->pos)){
$this->current = null;
$this->pos = -1;
return;
}
// Skip what we have read now
$this->current = $match[2];
$this->pos += strlen( $match[1]) + strlen( $match[2]) + strlen($match[3]);
// We're trying to iterate past string
if( $this->pos >= strlen($this->str)){
$this->pos = -1;
}
}
// Okay, we're done? :)
function valid() {
return ($this->pos > -1);
}
}
И если вы будете использовать его на более сложной строке:
$a = new WordsIterator("Progress in Veterinary Science. And, make it !more! interesting!\nWith new line.");
foreach( $a as $i){
echo $i;
echo "\n";
}
Получите ли вы ожидаемый результат:
Progress
in
Veterinary
Science
And
make
it
more
interesting
With
new
line
Таким образом, вы можете легко использовать $i[0]
для извлечения первой буквы. Вы, вероятно, видите, что это более эффективное решение, чем разбиение всей строки в памяти (всегда используйте как можно меньше памяти). Вы также можете легко изменить это решение для работы с непрерывным чтением файлов и т. Д.