2016-06-14 4 views
1

У меня есть строка, например:Как отрезать строку от начала до второй последней точки строки?

cats, e.g. Barsik, are funny. And it is true. So, 

И я хочу, чтобы получить в результате:

cats, e.g. Barsik, are funny. 

Мой попробовать:

mb_ereg_search_init($text, '((?!e\.g\.).)*\.[^\.]'); 
$match = mb_ereg_search_pos(); 

Но он получает позицию второй точки (после слова «истина»).

Как получить желаемый результат?

+5

Ваше название вводит в заблуждение, как вам нужно, чтобы соответствовать до первой полной остановки, что указывает на конец предложения.Вот наивный подход: '' ~ (?

+0

@Wiktor Stribiżew, спасибо – mnv

+0

Есть и другие сокращения, это не будет работать во всех случаях. –

ответ

1

Поскольку для вас работает наивный подход, я отправляю ответ. Однако обратите внимание, что определение конца предложения является очень сложной задачей для регулярного выражения, и хотя это возможно в какой-то мере, для этого следует использовать пакет NLP.

Сказав это, я предложил использовать

'~(?<!\be\.g)\.(?=\s+\p{Lu})~ui' 

Регулярного выражение соответствует любой точке (\.), не предшествуют с целым словом e.g (см отрицательных назад '(?<!\be\.g)), но следует с 1 или больше пробелов (\s+), за которым следует 1 заглавная буква Юникода \p{Lu}.

См regex demo

Дело нечувствителен i модификатор не влияет на какие \p{Lu} матчей.

Редактор ~u необходим, так как вы работаете с текстами Unicode (например, на русском).

Чтобы получить индекс первого вхождения, используйте функцию preg_match с флагом PREG_OFFSET_CAPTURE. Вот немного упрощена регулярное выражение вы указали в комментариях:

preg_match('~(?<!т\.н)(?<!т\.к)(?<!e\.g)\.(?=\s+\p{L})~iu', $text, $match, PREG_OFFSET_CAPTURE); 

Посмотреть lookaheads выполняются один за другим, и в том же месте в строке, таким образом, вы не должны дополнительно сгруппировать их внутри положительный предпросмотр , См. regex demo.

IDEONE demo:

$re = '~(?<!т\.н)(?<!т\.к)(?<!e\.g)\.(?=\s+\p{L})~iu'; 
$str = "cats, e.g. Barsik, are funny. And it is true. So,"; 
preg_match($re, $str, $match, PREG_OFFSET_CAPTURE); 
echo $match[0][1]; 
0

Вот два подхода, чтобы получить подстроку от начала до второй последней . позиции исходной строки:

  • с использованием strrpos и substr функции:

    $str = 'cats, e.g. Barsik, and e.g. Lusya are funny. And it is true. So,'; 
    $len = strlen($str); 
    $str = substr($str, 0, (strrpos($str, '.', strrpos($str, '.') - $len - 1) - $len) + 1); 
    
    print_r($str); // "cats, e.g. Barsik, and e.g. Lusya are funny." 
    
  • с использованием array_reverse, str_split и array_search функции:

    $str = 'cats, e.g. Barsik, and e.g. Lusya are funny. And it is true. So,'; 
    $parts = array_reverse(str_split($str)); 
    $pos = array_search('.', $parts) + 1; 
    $str = implode("", array_reverse(array_slice($parts, array_search('.', array_slice($parts, $pos)) + $pos))); 
    
    print_r($str); // "cats, e.g. Barsik, and e.g. Lusya are funny." 
    
Смежные вопросы