Помогите с регулярными выражениями (Parsing Wikipedia Markup) в PHP
У меня есть этот текст, который я хочу удалить со страницы, которую я загружаю из Википедии.
{{Historical populations|type=USA
| 1698|4937
| 1712|5840
| 1723|7248
| 1737|10664
| 1746|11717
| 1756|13046
| 1771|21863
| 1790|33131
| 1800|60515
| 1810|96373
| 1820|123706
| 1830|202589
| 1840|312710
| 1850|515547
| 1860|813669
| 1870|942292
| 1880|1206299
| 1890|1515301
| 1900|3437202
| 1910|4766883
| 1920|5620048
| 1930|6930446
| 1940|7454995
| 1950|7891957
| 1960|7781984
| 1970|7894862
| 1980|7071639
| 1990|7322564
| 2000|8008288
| 2008*|8363710
|footnote=Beginning 1900, figures are for consolidated city of five boroughs. Sources: 1698–1771,{{cite book|last=Greene and Harrington|first=|title=American Population Before the Federal Census of 1790|publisher=|location=New York|year=1932|isbn=|pages=}}, as cited in: {{cite book|last=Rosenwaike|first=Ira|title=Population History of New York City|publisher=Syracuse University Press|location=Syracuse, N.Y.|year=1972|isbn=0815621558|page=8}} 1790–1990,Gibson, Campbell.[http://www.census.gov/population/www/documentation/twps0027.html Population of the 100 Largest Cities and Other Urban Places in the United States:1790 to 1990], [[United States Census Bureau]], June 1998. Retrieved June 12, 2007. *2008 est[http://factfinder.census.gov/servlet/SAFFPopulation?_event=Search&geo_id=16000US3403940&_geoContext=01000US%7C04000US34%7C16000US3403940&_street=&_county=new+york+city&_cityTown=new+york+city&_state=04000US36&_zip=&_lang=en&_sse=on&ActiveGeoDiv=geoSelect&_useEV=&pctxt=fph&pgsl=160&_submenuId=population_0&ds_name=null&_ci_nbr=null&qr_name=null®=null%3Anull&_keyword=&_industry=Census Data for New York city, New York], [[United States Census Bureau]]. Retrieved June 12, 2007.
}}
Следующую часть я также хочу сохранить в виде простого текста (но не включая части, обернутые "{{" и "}}"
New York is the most populous city in the United States, with an estimated 2008 population of 8,363,710(up from 7.3 million in 1990). This amounts to about 40.0% of New York State's population and a similar percentage of the metropolitan regional population. Over the last decade the city's population has been increasing and demographers estimate New York's population will reach between 9.2 and 9.5 million by 2030.{{cite web |title=New York City Population Projections by Age/Sex and Borough, 2000-2030 |publisher=[[New York City Department of City Planning]] |month=December | year=2006 |url=http://www.nyc.gov/html/dcp/pdf/census/projections_report.pdf |format=PDF |accessdate=2008-09-01}} See also {{cite news |last=Roberts, Sam |title=By 2025, Planners See a Million New Stories in the Crowded City |publisher=New York Times |date=February 19, 2006 |url=http://www.nytimes.com/2006/02/19/nyregion/19population.html?ex=1298005200&en=c586d38abbd16541&ei=5090&partner=rssuserland&emc=rss |accessdate=2008-09-01}}
Благодарю.
3 ответа
В настоящее время я использую следующий код для очистки вики-страницы, например, такой:
http://en.wikipedia.org/wiki/Tel_Aviv (вы можете увидеть разметку, нажав "изменить эту страницу"
Я получил это возвращено:
"и уступил своей репутации" Средиземноморского мегаполиса, который никогда не спит ". Редакция Haaretz Это финансовая столица страны и крупный центр исполнительских искусств и бизнеса. Городской район Тель-Авива является вторым по величине городским хозяйством на Ближнем Востоке и считается 42-е место среди мировых городов по индексу глобальных городов Foreign Policys 2008. Это также самый дорогой город в регионе и 17-й самый дорогой город в мире. Стоимость жизни в Израиле высока, а Тель-Авив является его самым дорогим городом. По данным Mercer, кадровой консалтинговой компании, базирующейся в Нью-Йорке, по состоянию на 2008 год Тель-Авив является самым дорогим городом на Ближнем Востоке и 14-м самым дорогим в мире. Он отстает от Сингапура и Парижа и только впереди Сиднея и Дублина в этом отношении. Для сравнения, Нью-Йорк занимает 22-е место ".
Что не правильно, ожидаемый результат должен быть:
Тель-Авив-Яффо (иврит: תֵּל־אָבִיב-יָפוֹ; арабский: تل أبيب, Tall ʼAbīb), обычно называемый Тель-Авивом, является вторым по величине городом в Израиле, с предполагаемой численностью населения 393 900 человек. Город расположен на израильском побережье Средиземного моря, с площадью 51,8 квадратных километров. Это самый большой и самый густонаселенный город в столичном регионе Гуш-Дан, где с 2008 года проживает 3,15 миллиона человек. Город управляет муниципалитетом Тель-Авив-Яффо, возглавляемым Роном Хулдаем.
Для этого кода PHP:
function clean_wiki_text($text)
{
// first get rid of UGC HTML tags
$text = strip_tags($text);
// keep convert tag
$text = preg_replace("/\{\{convert\|([^\|]+)\|([^\|]+)\|[^\}]+\}\}/", "$1$2", $text);
// remove large blocks (treat as tags)
$text = preg_replace("/(<![^>]+>)/", '', $text);
$text = preg_replace('/\{\{\s?/', '<', $text);
$text = str_replace('}}', ' />', $text);
$text = str_replace('<! />', '', $text);
// more wiki formatting
$text = preg_replace("/'{2,6}/", '', $text);
$text = preg_replace("/[=\s]+External [lL]inks[\s=]+/", '', $text);
$text = preg_replace("/[=\s]+See [aA]lso[\s=]+/", '', $text);
$text = preg_replace("/[=\s]+References[\s=]+/", '', $text);
$text = preg_replace("/[=\s]+Notes[\s=]+/", '', $text);
$text = preg_replace('/\{\{([^\}]+)\}\}/', '', $text);
// drop page link text
$text = preg_replace('/\[\[([^:\|\]]+)\|([^:\]]+)\]\]/', "$2", $text);
// or keep it with preg_replace('/\[\[([^:\|\]]+)\|([^:\]]+)\]\]/', "$1 ($2)", $text);
$text = preg_replace('/\(\[[^\]]+\]\)/', '', $text);
$text = preg_replace('/\[\[([^:\]]+)\]\]/', "$1", $text);
$text = preg_replace('/\*?\s?\[\[([^\]]+)\]\]/', '', $text);
$text = preg_replace('/\*\s?\[([^\s]+)\s([^\]]+)\]/', "$2", $text);
$text = preg_replace('/\n(\*+\s?)/', '', $text);
$text = preg_replace('/\n{3,}/', "\n\n", $text);
$text = preg_replace('/<ref[^>]?>[^>]+>/', '', $text);
$text = preg_replace('/<cite[^>]?>[^>]+>/', '', $text);
$text = preg_replace('/={2,}/', '', $text);
$text = preg_replace('/{?class="[^"]+"/', "", $text);
$text = preg_replace('/!?\s?width="[^"]+"/', "", $text);
$text = preg_replace('/!?\s?height="[^"]+"/', "", $text);
$text = preg_replace('/!?\s?style="[^"]+"/', "", $text);
$text = preg_replace('/!?\s?rowspan="[^"]+"/', "", $text);
$text = preg_replace('/!?\s?bgcolor="[^"]+"/', "", $text);
$text = trim($text);
$text = preg_replace('/\n\n/', "<br />\n<br />\n", $text);
$text = preg_replace('/\r\n\r\n/', "<br />\r\n<br />\r\n", $text);
/*
$config = array(
'show-body-only' => true,
'clean' => false,
'wrap' => 0,
'show-warnings' => 0,
'show-errors' => 0,
'enclose-block-text' => false,
'vertical-space' => true,
'output-html' => true
);
// Tidy
$tidy = new tidy;
$tidy->parseString($text, $config, 'utf8');
$tidy->cleanRepair();
$text = $tidy->value;
*/
$extras = array(
// "/\((.*?)\)/is" => "",
"/\[(.*?)\]/is" => ""
);
$text = preg_replace(array_keys($extras), array_values($extras), $text);
$text = str_replace(" ,", ',', $text);
$text = str_replace(", ", ',', $text);
$text = str_replace(",", ', ', $text);
$text = str_replace("(, ", '(', $text);
$text = str_replace(";,", ',', $text);
// lets keep it plain plain plain
$text = strip_tags($text);
// $text = preg_replace('/\s\s+/', ' ', $text);
$text = str_replace("|-", '', $text);
$text = str_replace("|}", '', $text);
$text = str_replace("|", '', $text);
$text = str_replace('()', '', $text);
$text = str_replace(' ', ' ', $text);
$text = trim($text);
$text_arr = preg_split('/[\r\n]+/', $text, -1, PREG_SPLIT_NO_EMPTY);
$result = "";
foreach ($text_arr as $paragraph) {
if ( mb_strlen(trim($paragraph)) > 30 ) {
$result[] = $paragraph;
}
}
return $result;
}
Просто угадайте здесь, но не будет ли проще и безопаснее использовать библиотеку разметки Википедии (в комплекте с Mediawiki), превратить ее в HTML, а затем проанализировать ее, используя любую библиотеку XML, которая вам удобна?
Документацию по API можно найти по адресу http://svn.wikimedia.org/doc/ (в Parser
модуль) и выглядит не очень сложно. По сути, все, что вам нужно сделать, это что-то вроде следующего:
<?php
require_once '/path/to/mediawiki/Parser.php';
// also include whatver classes Parser depends on or use Mediawiki's autoload
// mechanism if it has any
// retrieve the content of your page in $content
$parser = new Parser();
$html = $parser->parse($content);
$simplexml = simplexml_load_string($html);
Теперь у вас есть очень удобный объект SimpleXML для игры. Конечно, это работает только в том случае, если анализатор Mediawiki создает корректный XML (что, я уверен, он делает).
Кроме того, если бы в Mediawiki был какой-то механизм автозагрузки, было бы легко найти его, ища __autoload
или же spl_autoload_register
в кодовой базе Mediawiki.
Надеюсь, поможет!
Действительно трудно сделать регулярное выражение, когда приведен только один пример - из моего собственного опыта в очистке страниц Википедии я знаю, что другие страницы, скорее всего, будут выглядеть немного иначе. Просто чтобы соответствовать вашему примеру просто:
{{.+?}}\n
Это работает только в том случае, если после удаляемой детали есть новая строка, и если вы укажете DOTALL
а также MULTILINE
, Сопоставьте все пары двойных фигурных скобок и вещи внутри:
{{[^}]+}}
Вы можете попробовать выполнить несколько прогонов, каждый из которых удалит другую нежелательную часть - я сомневаюсь, что вполне выполнимо сопоставить все, что вам нужно, в одном регулярном выражении.