我有一些字符串,例如:
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();
但是它获得了第二个点的位置(在#34之后;真的")。
如何获得理想的结果?
答案 0 :(得分:1)
由于天真的方法适合你,我发布了一个答案。但是,请注意,检测句子结束对于正则表达式来说是一项非常困难的任务,尽管在某种程度上可以使用,但是应该使用NLP包。
话虽如此,我建议使用
'~(?<!\be\.g)\.(?=\s+\p{Lu})~ui'
正则表达式匹配任何前面没有整个单词\.
的点(e.g
)(请参阅否定的lookbehind (?<!\be\.g)
),但后面跟着一个或多个空格( \s+
)后面跟着1个大写的Unicode字母\p{Lu}
。
请参阅regex demo
不区分大小写的i
修饰符不会影响\p{Lu}
匹配的内容。
由于您使用的是Unicode文本(如俄语),因此需要~u
修饰符。
要获取第一次出现的索引,请使用带有preg_match
标志的PREG_OFFSET_CAPTURE
函数。以下是您在评论中提供的简化的正则表达式:
preg_match('~(?<!т\.н)(?<!т\.к)(?<!e\.g)\.(?=\s+\p{L})~iu', $text, $match, PREG_OFFSET_CAPTURE);
看到前瞻一个接一个地执行,并且在字符串中的相同位置,因此,您不必另外将它们分组到正向前瞻中。请参阅regex 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];
答案 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."