Выражение Xpath для первого предложения на странице

Я ищу выражение Xpath для первого предложения в абзаце.

<p>
A federal agency is recommending that White House adviser Kellyanne Conway be 
removed from federal service saying she violated the Hatch Act on numerous 
occasions. The office is unrelated to Robert Mueller and his investigation.
</p>

Результат должен быть:

A federal agency is recommending that White House adviser Kellyanne Conway be 
removed from federal service saying she violated the Hatch Act on numerous 
occasions.

Я пробовал несколько вещей безрезультатно.

$expression = '/html/body/div/div/div/div/p//text()';

Нужно ли мне использовать: //p[ends-with или, может быть, substring-before?

Вам нужно указать, какую версию XPath вы используете. Такого рода вещи намного проще в XPath 2.0 или более поздних версиях. Вы ссылаетесь на ends-with(), для которого требуется XPath 2.0, но вы также упоминаете PHP, который предполагает, что вы ограничены 1.0.

Michael Kay 14.06.2019 00:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
1
670
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не сможете анализировать естественный язык с помощью XPath, но вы можете получить подстроку до первой точки включительно следующим образом:

substring(/p,1,string-length(substring-before(/p,"."))+1)

Обратите внимание, что это может быть не «первое предложение», если есть сокращения или другие лексические употребления точки перед окончанием первого предложения, если первое предложение заканчивается другой формой пунктуации и т. д.


Альтернативно и более кратко:

concat(substring-before(/p, "."), ".")

Умная идея Кредит:тыс. Вт в комментариях.

Думаю, я мог бы также взорвать() его и захватить первый элемент в массиве. Вероятно, пытается сделать слишком много с XPath.

Karl Hill 13.06.2019 22:17

Вышеупомянутое примерно так же хорошо, как вы получите в одном простом XPath; explode() лучше не будет. Вам нужно будет использовать библиотеку NLP для работы на семантическом уровне предложений, а не на лексическом уровне пунктуации, чтобы действительно сделать это правильно.

kjhughes 13.06.2019 23:42

Я думаю, что substring-before(/p,'.') достаточно. Остальная часть выражения, чтобы получить также точку, может запутать substring-before() семантику.

Alejandro 14.06.2019 00:20

@Alejandro: Действительно, сначала я написал только substring-before(/p,'.'), но потом я увидел, что ОП запросил, чтобы «результат был» выводом, включающим точку, поэтому я подумал, что сделаю еще один шаг. Вы правы, однако, substring-before() важнее всего.

kjhughes 14.06.2019 03:35

Вы можете просто добавить точку еще раз: concat(substring-before(/p, "."), ".")

ThW 15.06.2019 22:54

Здесь нет действительно хорошего способа сделать это на уровне Xpath. PHP имеет только Xpath 1.0 и поддерживает только базовые строковые операции. Ничего, что может учитывать локаль/язык. Однако у самого PHP есть кое-что для этого в ext/intl.

Поэтому извлеките текстовое содержимое узла элемента абзаца с помощью DOM+Xpath в виде строки и извлеките из него первое предложение.

IntlBreakIterator может разделить строку в соответствии с правилами, специфичными для локали/языка.

$html = <<<'HTML'
<p>
A federal agency is recommending that White House adviser Kellyanne Conway be 
removed from federal service saying she violated the Hatch Act on numerous 
occasions. The office is unrelated to Robert Mueller and his investigation.
</p>
HTML;

$document = new DOMDocument();
$document->loadXML($html);
$xpath = new DOMXpath($document);

// fetch the first paragraph in the document as string
$summary = $xpath->evaluate('string((//p)[1])');
// create a break iterator for en_US sentences.
$breaker = IntlBreakIterator::createSentenceInstance('en_US');
// replace line breaks with spaces before feeding it to the breaker
$breaker->setText(str_replace(["\r\n", "\n"], '', $summary));

$firstSentence = '';
// iterate the sentences
foreach ($breaker->getPartsIterator() as $sentence) {
  $firstSentence = $sentence;
  // break after the first sentence
  break;
}

var_dump($firstSentence);

Выход:

string(164) "A federal agency is recommending that White House adviser Kellyanne Conway be removed from federal service saying she violated the Hatch Act on numerous occasions. "

Кроме того, DOMXpath позволяет регистрировать функции PHP и вызывать их из выражения Xpath. Если вам нужна эта логика на уровне Xpath (чтобы использовать их в условиях), это возможно.

Это полезное дополнение, использующее язык хостинга.

kjhughes 16.06.2019 01:13

Другие вопросы по теме