[Powered by Google Translate] [Seminar: Pattern Pagtutugma sa Mga Regular Expression] [John Mussman-Harvard University] [Ito ay CS50.-CS50.TV] Okay. Well, maligayang pagdating sa lahat. Ito ay CS50 2012. Ang pangalan ko ay John, at ako ay pakikipag-usap ngayon tungkol sa mga regular na expression. Mga regular na expression ay pangunahing isang kasangkapan, ngunit din minsan ginagamit sa code aktibong upang lubos na tumutugma sa mga pattern at mga string. Kaya narito ang isang web comic mula xkcd. Sa comic doon ay isang pagpatay misteryo kung saan ang mga killer ay may Sinundan isang tao sa bakasyon, at ang protagonists kailangang maghanap sa pamamagitan ng 200 megabytes ng mga email na naghahanap para sa isang address. At ang mga ito ay tungkol sa upang bigyan up kapag ang isang tao na nakakaalam ng mga regular na expression - siguro isang superhero - swoops down at nagsusulat ng ilang mga code at malulutas nito ang pagpatay misteryo. Kaya siguro na magiging isang bagay na ikaw ay empowered upang gawin pagkatapos ng seminar na ito. Lamang namin ay pagpunta sa magbigay ng isang maikli subalit malaman panimula sa ang wika at bibigyan ka ng sapat na kakayahan upang pumunta pagkatapos ng higit pang mga mapagkukunan sa iyong sariling. Kaya mga regular na expression tumingin talaga ganito. Ito ay isang regular na expression sa Ruby. Ito ay hindi lubha iba't ibang mga wika. Mayroon kaming lamang sa slashes upang simulan at markahan ang mga regular na expression sa Ruby. At ito ay isang regular na expression upang tumingin para sa email address na pattern. Kaya naming makita sa unang bit hitsura para sa anumang mga alphanumeric character. Iyon ay dahil sa ang email address na madalas mayroon na magsimula sa isang alpabetikong character. At pagkatapos ay ang anumang mga espesyal na character na sinundan ng @ simbolo. At pagkatapos ay ang parehong bagay para sa domain name. At pagkatapos ay sa pagitan ng 2 at 4 na mga character upang tumingin para sa. Com,. Net, at iba pa. Kaya na ay isa pang halimbawa ng mga regular na expression. Kaya regular na expression ay mga protocol para sa paghahanap ng patters sa teksto. Gawin nila mga paghahambing, mga pagpili, at pamalit. Kaya isang third halimbawa ay sa paghahanap ng lahat ng mga numero ng telepono na nagtatapos sa 54 sa isang direktoryo. Kaya bago David rips up ang CS50 direktoryo kami maaaring maghanap para sa sa isang pattern na kung saan mayroon kaming mga panaklong pagkatapos 3 mga numero ay matatapos panaklong, 3 higit pang mga numero, isang gitling, 2 numero, at pagkatapos ay 54. At iyon ay magiging lubos kung paano namin dumating up sa isang regular na expression upang maghanap para sa na. Kaya may mga - namin nagawa ang ilang mga bagay sa CS50 na Medyo parang mga regular na expression, kaya - halimbawa - sa dictionary.C file para sa spell check hanay problema maaaring ginamit mo fscanf upang basahin sa isang salita mula sa diksyunaryo. At maaari mong makita ang porsyento 45s ay naghahanap para sa isang string ng 45 mga character. Kaya ito ay medyo tulad ng isang hindi pa ganap regular na expression. At maaari kang magkaroon ng anumang 45 mga character na magkasya ang bayarin sa doon at pumili ng mga up. At pagkatapos ay ang pangalawang halimbawa sa pinakahuling problema web programming itakda sa distro code para sa php namin talagang gawin ay may isang simpleng regular na expression. At isa na ito lamang lamang na naghahanap upang suriin kung ang mga web page na ito ay naipasa sa tumutugma sa alinman sa pag-login o mag-logout magrehistro. PHP. At pagkatapos ay bumabalik totoo o hindi batay sa mga regular na expression na pagtutugma. Kaya kapag mo ginagamit ang karaniwang expression? Bakit nandito ka ngayon? Kaya hindi mo nais na gamitin ang mga regular na expression kapag mayroong isang bagay na ang ipinapakita ng trabaho para sa iyo kahit na mas madali. Kaya XML at HTML ay aktwal na medyo nakakalito sumulat ng mga regular na expression para sa bilang ay namin makita sa ilang sandali. Kaya may mga nakalaang parsers para sa mga wikang iyon. Kailangan mo ring maging okay sa kalakalan offs at katumpakan madalas. Kung sinusubukan - kaya namin nakita ang isang regular na expression para sa isang email address, pero sabihin mo gusto ang isang tiyak na address ng email at dahan-dahan ang regular na expression ay maaaring maging mas kumplikadong bilang ito ay naging mas tumpak. Kaya na magiging isa kalakalan off. Mayroon kang upang matiyak na okay ka sa paggawa na may mga regular na expression. Kung alam mo kung ano mismo ang iyong hinahanap maaaring gumawa ng higit pa pakiramdam ang ilalagay sa oras at magsulat ng mas epektibong pang-parse. At sa wakas ay may makasaysayang mga isyu sa ayos ng mga expression at mga wika. Regular na expression ay aktwal na magkano ang mas malakas kaysa regular na mga expression sa bawat sabihin sa isang pormal na kahulugan. Kaya hindi ko nais upang pumunta masyadong malayo sa pormal na teorya, ngunit karamihan sa mga wika na aming code sa aktwal ay hindi regular. At ito ang dahilan kung bakit karaniwang expression kung minsan ay hindi isinasaalang-alang ang lahat na secure. Kaya talaga doon ay isang Chomsky hierarchy para sa mga wika, at mga regular na expression ay bumuo up gamit ang unyon, pagdudugtong, at ang pagpapatakbo Kleene star na namin makita ang ilang mga minuto. Kung ikaw ay interesado sa teorya doon ay masyadong maraming nagaganap doon sa ilalim ng hood. Kaya ang isang maikling kasaysayan - para lamang sa konteksto dito - regular na set up ay dumating sa 1950s, at pagkatapos ay nagkaroon kami simpleng editor na Isinama mga regular na expression - lamang naghahanap para sa mga string. Grep - na kung saan ay isang command line tool - ay isa sa mga unang napaka-tanyag na mga tool na inkorporada regular na mga expression sa 1960. Sa '80s, Perl ay itinayo - ay isang programming language na isinasama mga regular na expression napaka kitang-kita. At pagkatapos ay mas kamakailan lamang namin ay nagkaroon Perl compatible regular expression protocol talaga sa iba pang mga wika na gumagamit ng magkano ang parehong syntax. Siyempre ang pinaka-mahalagang kaganapan noon ay sa 2008 kung saan nagkaroon ng unang Pambansang Karaniwang Expression Day, naniniwala na ako ay Hunyo 1 kung nais mong ipagdiwang na. Muli, lamang ng kaunti kaunti pang teorya dito. Kaya may mga ilang iba't ibang mga paraan ng paggawa mga regular na expression. Isang simpleng paraan ay upang bumuo ng mga expression na kayo ay pagpunta sa tumakbo sa string interpret - isa lamang bumuo ng isang maliit na mini-program na Pag-aaralan ng mga piraso ng isang string at makita, "Oh, ito ay magkasya sa regular na expression o hindi?" At pagkatapos ay tumakbo na. Kaya kung mayroon kang isang napakaliit na regular na expression, ito ay marahil ang pinakamahusay na paraan upang gawin ito. At pagkatapos ay kung ikaw - isa pang pagpipilian ay upang panatilihin ang reconstructing expression bilang pumunta ka, at iyon ay ang gayahin posibilidad. At ang mga unang bahagi ng pagtatangka sa mga regular na expression algorithm ay medyo simple at relatibong mabilis, ngunit hindi magkaroon ng maraming kakayahang umangkop. Kaya gawin kahit na ang ilan sa mga bagay na kami ay pagpunta upang tumingin sa ngayon kami ay nagkaroon na gawin mas kumplikadong mga regular na expression pagpapatupad na potensyal na mas mas mabagal; gayon ay isang bagay upang tandaan Mayroon ding isang regular na expression pagtanggi ng pag-atake iba't-ibang na maningning na tagumpay ang mga potensyal na para sa mga mas bagong pagpapatupad ng regular na expression upang maging napaka-komplikadong. At sa halos parehong kahulugan na nakita natin sa pag-atake buffer overflow, mayroon kang pag-atake na gumagana sa pamamagitan ng paggawa ng recursive loop na sumobra ang kapasidad ng memorya. At sa pamamagitan ng ang paraan Regexen ay isa sa mga opisyal na pangmaramihan ng mga regular na expression sa pamamagitan ng pagkakatulad sa mga baka sa Anglo-Sahon. Okay, sa gayon ang Library Python marami sa inyo dito sa taong may mga Mac, sa gayon ay maaari mo talagang hilahin ito up sa iyong screen. Mga regular na expression ay binuo sa Python. At kaya Python ay preloaded sa mga Mac at available din online sa link na ito. Kaya't kung ikaw ay nanonood maaari mong i-pause at siguraduhin na mayroon kang Python maglaro bilang namin sa paligid dito. May ng manu-manong online, kaya kung ikaw i-type lamang sa Python iyong computer makikita mo na ang bersyon ay lumalabas sa terminal. Kaya ko na ibinigay ng isang link sa mga manu-manong para sa 2 Bersyon ng Python pati na rin ang isang impostor sheet. May Bersyon 3 ng Python, ngunit ang iyong Mac ay hindi kinakailangang ay may na preloaded. Kaya hindi lubha naiiba. Okay, kaya ang ilang mga pangunahing kaalaman sa paggamit ng mga karaniwang expression sa Python. Kaya dito ginamit ko isang napaka-simpleng expression, kaya ko ginawa Python muling pag-import at pagkatapos ay kinuha ang resulta ng re.search. At paghahanap ay tumatagal ng 2 na mga argumento. Ang una ay ang regular na expression, at ang pangalawa ay ang teksto o string na gusto mong pag-aralan. At pagkatapos ay ako naka-print out ang result.group. Kaya ito ay ang 2 pangunahing pag-andar namin ay pumunta upang makita ngayon sa pag-aaral tungkol sa mga regular na expression. Kaya lang na pinaghihiwa-hiwalay ang mga regular na expression dito h at pagkatapos \ w at pagkatapos m kaya \ w lamang ang tumatanggap ng anumang alpabetikong character sa doon. Kaya dito kami ay naghahanap para sa isang "h" at pagkatapos ay isa pang alpabetikong character at pagkatapos ay i-m, kaya dito na tumutugma sa ham in, "Abraham Lincoln at ham sandwich." Ito ang resulta ng pangkat na iyon. Isa pang bagay na maaari naming gawin ay gamitin ang aming bago string ng teksto sa Python. Kaya hulaan ko ako ay sige at hilahin na up dito. Python-import muli. At kung ako ay upang gawin ang parehong bagay - hayaang sabihin sa amin ang teksto, "Abraham," ipaalam sa amin mag-zoom in - doon kami pumunta. Teksto ay, "Abraham kumakain ham." Okay, at pagkatapos ay magreresulta = re.search. At pagkatapos ay aming mga expression ay maaaring maging h, at pagkatapos ay kong gawin tuldok m. Kaya tuldok lamang tumatagal ng anumang mga character na ay hindi isang bagong linya kasama ang mga numero, porsyento ng mga karatula, anumang bagay na tulad nang. At pagkatapos ay i-text - boom - at pagkatapos ay i-result.group--oo. Kaya na lamang kung paano ipatupad ang pangunahing pagpapagana dito. Kung nagkaroon kami ng text singsing na - na mabaliw teksto - Kasama sabihin ng maraming pabalik slashes at mga string sa loob at mga bagay na maaaring magmukhang escape sequence, pagkatapos namin marahil nais na gamitin ang raw na input ng teksto upang masiguro na tatanggapin. At na lang kamukha na. Kaya kung humahanap kami bawat isa sa kanila doon sa hindi kami makahanap ng anumang bagay. Ngunit iyon ay kung paano mo ipatupad ito; lang bago ang string ng ang regular na expression na ilagay ang titik r. Okay, kaya ipaalam sa amin panatilihin ang pagpunta. Ang lahat ng mga karapatan - kaya ipaalam sa amin tumingin sa isang ilang mga pattern ng paulit-ulit dito. Kaya ang isang bagay na gusto mong gawin ay ulitin ang mga bagay bilang ikaw ay naghahanap sa pamamagitan ng text. Kaya na gawin ang isang sinusundan ng anumang bilang ng mga b - gawin mo ab *. At pagkatapos ay mayroong isang serye ng iba pang mga panuntunan masyadong. At maaari mong tingnan ang lahat ng mga ito up; kukunin ko na lang tumakbo sa pamamagitan ng ilan sa mga pinaka-karaniwang ginagamit na mga bago. Kaya ab + ay isang sinusundan ng anumang N mas malaki kaysa sa 0 ng b. ab? ay isang sinusundan ng 0 o 1 ng b. ab {N} ay sinundan sa pamamagitan ng N ng b, at pagkatapos ay iba pa. Kung ikaw ay may 2 numero sa kulot tirante ka ng pagtukoy ng hanay na maaaring maging posibleng tumugma. Kaya tayo ay tumingin nang higit pa sa isang ilang mga pattern ng paulit-ulit sa isang minuto. Kaya 2 mga bagay na dapat tandaan kapag gumagamit ng mga pattern na tumutugma sa mga kasangkapan dito. Kaya natin na nais namin upang tumingin sa mga Hm ng, "Abraham Lincoln ginagawang ham sandwich." Kaya ako ay nagbago Abraham Lincoln pangalan sa Abraham. At ngayon kami ay naghahanap para sa kung ano ay ibinalik sa pamamagitan ng pagpapaandar na ito sa paghahanap, at ito nagbabalik lamang ang ham sa kasong ito. At ginagawa nito na dahil lamang sa paghahanap natural tumatagal ang pinaka-kaliwa queue. At lahat ng mga regular na expression maliban kung tinukoy mo kung hindi man ay gawin na. Kung gusto naming mahanap ang lahat doon ay isang katangian para sa na - hanapin ang lahat. Kaya na maaari lamang hitsura ng lahat = re.findall ('h.m', text) at pagkatapos all.group (). Ang lahat ng mga gumagawa ng parehong mga hamon at hamon; sa kasong ito kapwa ng mga string sa Abraham bawat hamon. Kaya na ay isa pang pagpipilian. Mahusay. Ang iba pang mga bagay na dapat tandaan ay na ang mga regular na expression tumagal ang pinakamalaking intuitively. Ipaalam sa amin tumingin sa halimbawang ito. Aming ginawa na kaliwa karamihan sa mga search dito, at pagkatapos ay sinubukan ko ng mas malaking paghahanap gamit ang Kleene operator star. Kaya para sa, "Abraham Lincoln ginagawang sandwich ham," at ako lamang Nakakuha pabalik m bilang isang resulta. Ang dahilan sa pagkakamali noon na maaaring ako nagsagawa ng anumang numero ng h ay dahil hindi ko tukuyin ang anumang bagay upang pumunta sa pagitan ng h at m. Ang tanging mga halimbawa doon na nagkaroon m - ang mga halimbawa lamang doon na may m sa loob nito at anumang bilang ng h ni lamang ay ang string m. Pagkatapos Sinubukan kong ito muli; ko sinabi, "Okay, ipaalam sa amin kumuha ang aktwal na pinakamalaking grupo dito." At pagkatapos ay ako ginawang h. * M, kaya lang na nagbabalik ng anumang bilang ng mga character sa pagitan ng h at m. At kung lamang ikaw ay nagsisimula out at pag-iisip, "Oh, okay, ito rin ay kumuha ako ng ham, "ito aktwal na tumatagal ng lahat ng bagay mula sa h sa Abraham Lincoln ang lahat ng mga paraan ng hanggang sa dulo ng ham. Ito ay matakaw; ito nakikita ng h - lahat ng mga ito ng iba pang teksto - m, at iyon ay kung ano ang aabutin in Ito ay isang partikular na kapansin-pansin - ito ay isang tampok ng aming makakaya din tukuyin ito para hindi matakaw paggamit ng iba pang mga function. Ngunit ito ay isang bagay na mayroon kami na dapat tandaan lalo na kapag tumitingin sa HTML teksto, na kung saan ay isang kadahilanan na regular na expression ay mahirap para sa mga HTML. Dahil kung mayroon kang isang bukas na HTML tag at pagkatapos ng maraming mga bagay-bagay sa gitna at pagkatapos ay sa ilang ibang mga HTML tag sarado magkano mamaya sa programa, lamang na iyong kinakain up ng maraming ng iyong HTML code marahil nang hindi sinasadya. Ang lahat ng mga karapatan - kaya mas espesyal na character, tulad ng maraming iba pang mga wika, makatakas namin ang paggamit ng slash. Kaya maaari naming gamitin ang mga tuldok upang tukuyin ang anumang mga character na maliban para sa isang bagong linya. Maaari naming gamitin ang escape w upang tukuyin ang anumang alpabetikong character. At sa pamamagitan ng pagkakatulad escape d para sa anumang integer - numerical character. Maaari naming tukuyin - maaari naming gamitin bracket upang tukuyin ang mga kaugnay na mga expression. Kaya ito ay tumatanggap ng a, b, c o. At maaari rin naming tukuyin o mga pagpipilian para sa alinman sa o b. Halimbawa - kung humahanap kami ng maraming mga posibilidad sa mga bracket kami maaaring gamitin ang operator o tulad ng sa - kaya ipaalam sa amin bumalik sa halimbawang ito dito. At ngayon, ipaalam sa amin kumuha - ipaalam sa amin bumalik sa halimbawang ito dito, at pagkatapos ay tumagal ae - kaya ito ay dapat ibalik - hulaan ko pa rin ito ni Abraham. Kaya ito - kung gagawin namin ang lahat - mahusay. Kaya ipaalam sa amin i-update ang teksto dito. "Abraham kumakain ham habang hemming kanyang -. Habang hemming" Mahusay. Lahat. Mahusay. Ngayon makuha namin ham, ham, at magtupi. Habang hemming - habang humuhuni sa kanya - habang humuhuni sa magtupi kanya. Mahusay. Parehong bagay. Ngayon ang lahat ay nagbabalik pa rin lang ang ham, ham, at magtupi nang walang tumatawag sa humingig o sa kanya. Mahusay - kaya kung ano ang gusto namin upang tumingin sa alinman na - sa gayon maaari rin naming gawin siya o - kami ay bumalik sa na. Okay - kaya - lahat ng mga karapatan - sa mga posisyong maaari mo ring gamitin ang kareta o ang dollar sign upang tukuyin na ikaw ay naghahanap para sa isang bagay sa simula o dulo ng isang string. O sa simula o dulo ng isang salita. Iyon ay isang paraan upang gamitin iyon. Okay - kaya ipaalam sa amin maglaro sa paligid na may isang bahagyang mas malaking bloke ng teksto. Ipaalam sa amin sabihin ang hilera na ito dito - ang pahayag na ito dito. Ang kapangyarihan ng mga regular na expression ay na maaari nilang tukuyin ang mga pattern hindi lang naayos character. Ipaalam sa amin gawin - ipaalam sa amin tumawag sa block na ito. Pagkatapos ay binabasa namin ang lahat ng na-in At pagkatapos ay may - ipaalam sa amin gawin ang lahat =; kaya kung ano ang ilang mga bagay na maaari kaming maghanap sa pakinabang dito? Maaari naming hanapin ang tainga expression. Hindi masyadong kawili-wili. Paano tungkol sa? Susubukan naming makita kung ano ang mangyayari. Nagbigay ako ng ito ng problema. Kaya ang anumang bilang ng mga bagay bago muling at lahat. Kaya dapat na ibalik ang lahat mula sa simula hanggang sa ang lahat ng muling marahil ng ilang beses. At pagkatapos dito kami ay may sa kapangyarihan ng mga regular na expression ay na sila Maaari tukuyin ang mga pattern hindi lamang mga character dito ay mga. Kaya ang lahat ng mga paraan ng hanggang sa ang huling re, ito makapagsimula sa kaliwa at karamihan ay matakaw. Ipaalam sa amin makita - ano pa ang maaari naming hanapin. Hulaan ko ang isang bagay na kung ikaw ay interesado sa naghahanap para sa mga pronouns siya at siya, maaari mong suriin para sa mga pagiging patas sa 0 o 1 at ang expression niya, at iyon ay marahil hindi pagpunta sa bumalik - oh, hulaan ko ito ibinalik niya dahil doon namin ang pagtingin sa kapangyarihan, sa araw na iyon, ay dito. Ipaalam sa amin subukan pagtukoy na ito ay may na dumating sa simula ng isang bagay. Ipaalam sa amin makita kung na patak off. Kaya maaari naming gawin taba, at mayroong hindi kami makakuha ng anumang bagay dahil siya at siya huwag mangyari ito sa parirala. Mahusay. Okay - kaya bumalik sa pusa dito. Kaya complex pattern ay nakakasama sa utak. Kaya na ang dahilan kung bakit ginagamit namin ang mga regular na expression upang maiwasan ang mga isyung ito. Kaya narito ang ilang mga iba pang mga kapaki-pakinabang na mga mode maaari mong i-play sa paligid na may. Kami ay tumingin sa paghahanap sa ngayon, ngunit maaari mo ring gamitin ang tugma, split, findall, at pangkat. Kaya iba pang mga cool na bagay na maaari mong gawin sa mga regular na expression bukod lamang naghahanap ng mga pattern ay tumatagal ng isang pattern at may hawak na ang lahat ng mga tugma - variable nito - at pagkatapos gamit ang mga nasa iyong code sa susunod. Iyon ay maaaring maging lubos na kapaki-pakinabang. Iba pang mga bagay na maaaring pagbibilang. Kaya maaari naming bilangin ang bilang ng mga kaso ng isang regular na expression pattern, at iyon ay kung ano ang maaari naming gamitin para sa mga grupo. At iba pang mga mode pati na din ang panahon. Kaya ko lang nais na makipag-usap nang kaunti nang higit pa tungkol sa iba pang mga paraan na maaari mong gamitin ang mga regular na expression. Kaya isang mas advanced na application ay nasa malabo pagtutugma. Kaya kung naghahanap ka para sa isang teksto para sa pagpapahayag, Julius Caesar, at nakikita mo ang alinman sa Gaius Julius Caesar o ang pangalan Julius Caesar sa iba pang mga wika, pagkatapos ay maaari mo ring isaalang-magtalaga ng ilang timbang sa mga halagang iyon. At kung ito ay malapit na sapat na - kung ito ay tumatawid sa isang tiyak na threshold - pagkatapos gusto mo upang magawang tanggapin Julius Caesar. Kaya may mga ilang iba't ibang mga pagpapatupad na para sa ilang iba pang mga wika pati na rin. Narito ang ilang mga iba pang mga tool, RegEx Pal - isang madaling-magamit na maliit na app sa online suriin kung ang iyong mga regular na expression ay binubuo nang tama. Mayroon ding mga nakapag-iisang tool na maaari mong patakbuhin mula sa iyong desktop tulad ng Ultra Pico, at pati na rin lamang cookbooks. Kaya kung ang iyong ginagawa sa isang proyekto na nagsasangkot ng isang tonelada ng mga regular na expression ito ay marahil ang lugar upang pumunta sa labas ng saklaw ng mga araw na ito. At pagkatapos lamang upang mabigyan ka ng ideya ng kung paano karaniwang mga ito ay mayroong grep sa Unix, Perl ay may built-in, at C mayroong PCRE para sa C. At pagkatapos ay ang lahat ng mga iba pang mga wika ay mayroon ding mga regular na expression pakete umaandar na may mahalagang parehong syntax kami nakakuha ng panlasa ng araw na ito. PHP, Java, Ruby, at iba pa. Maghanap sa Google Code ay talagang nagkakahalaga pagbanggit; ito ay isa sa mga kaugnay sa ilang mga aplikasyon out doon na nagbibigay-daan sa publiko na i-access ang database na gamit ang mga regular na expression. Kaya't kung tiningnan mo sa Google Code Search maaari mong makita ang code kung naghahanap ka para sa isang halimbawa ng kung paano ang isang function na maaaring magamit, maaari mong gamitin ang isang karaniwang expression upang makita na ang function na ginagamit sa lahat ng uri ng iba't ibang mga kaso. Maaari kang maghanap ng mga fwrite, at pagkatapos ay maaari mong hanapin ang bandila ng write o basahin kung ginusto isang halimbawa ng fwrite ginagamit sa kasong iyon. Kaya ang parehong bagay doon, at narito ang ilang mga sanggunian. Ito ay magagamit sa online pati na rin, kaya pagpunta pasulong kung Gusto mo upang tumingin sa Python, grep, Perl - gusto mo lamang upang makakuha ng ilang inspirasyon o kung nais mong upang tumingin nang higit pa sa teorya narito ang ilang mga mahusay na hangganan ng mundong off ang mga lugar. Maraming salamat sa inyo. [CS50.TV]