একটি রেজেক্স ম্যাচের অংশটি বের করুন


130

আমি এইচটিএমএল পৃষ্ঠা থেকে শিরোনামটি বের করতে একটি নিয়মিত প্রকাশ চাই। বর্তমানে আমার কাছে এটি রয়েছে:

title = re.search('<title>.*</title>', html, re.IGNORECASE).group()
if title:
    title = title.replace('<title>', '').replace('</title>', '') 

কেবলমাত্র <শিরোনাম> এর সামগ্রীগুলি নিষ্কাশনের জন্য কি কোনও নিয়মিত অভিব্যক্তি রয়েছে তাই আমাকে ট্যাগগুলি সরাতে হবে না?


5
বাহ আমি কেবলমাত্র একটি সাধারণ শিরোনাম উত্তোলনের জন্য পুরো HTML পৃষ্ঠাটি পার্স করার জন্য ডেকে আছি সমস্ত প্রতিক্রিয়া বিশ্বাস করতে পারি না। কি ওভারকিল!
হুজু

4
প্রশ্ন শিরোনাম এটি সব বলছে - উদাহরণস্বরূপ দেওয়া ঘটে এইচটিএমএল হতে, তবে সাধারণভাবে সমস্যা সাধারণ ...।
ফিল

উত্তর:


207

ক্যাপচারিত স্ট্রিংটি পুনরুদ্ধার করতে ( )রিজেক্সেপ এবং group(1)পাইথনে ব্যবহার করুন ( ফলাফলটি না পেলে re.searchফিরে আসবেন None, সুতরাং সরাসরি ব্যবহার করবেন নাgroup() ):

title_search = re.search('<title>(.*)</title>', html, re.IGNORECASE)

if title_search:
    title = title_search.group(1)

1
কোনও শিরোনাম পাওয়া না গেলে আপনি যদি কিছু না করেন, তবে গ্রুপ () সরাসরি ব্যবহার করা খারাপ জিনিস হবে কেন? (আপনি যেভাবেই ব্যতিক্রমটি ধরতে পারেন)
টনফা

1
হ্যাঁ, তবে বেশিরভাগ লোকেরা ব্যতিক্রমগুলি ভুলে যায় এবং রানটাইম এগুলি দেখলে তারা সত্যিই অবাক হয় :)
ক্রিজিসটফ ক্রোসো

চালাতে ভুলবেন না import reঅন্যথায় আপনি পাবেনNameError: name 're' is not defined
পাওয়ার

16

নোট করুন যে শুরু Python 3.8এবং অ্যাসাইনমেন্ট এক্সপ্রেশন (পিইপি 572) ( :=অপারেটর) এর পরিচিতি , ক্রিশিসটফ ক্রসোসের সমাধানের সাথে সামঞ্জস্যের ফলাফলটি যদি কেবলমাত্র একটি শর্তের মধ্যে পরিবর্তনশীল হিসাবে ধরা হয় এবং অবস্থার শরীরে পুনরায় ব্যবহার করা সম্ভব হয় :

# pattern = '<title>(.*)</title>'
# text = '<title>hello</title>'
if match := re.search(pattern, text, re.IGNORECASE):
  title = match.group(1)
# hello



4

আমি আপনাকে সুন্দর স্যুপের প্রস্তাব দিতে পারি। আপনার সমস্ত এইচটিএমএল ডকুমেন্টকে পার্স করার জন্য স্যুপ একটি খুব ভাল লিবিব।

soup = BeatifulSoup(html_doc)
titleName = soup.title.name

আমি যুক্ত করতে চাই, সেই সুন্দরদ্বারাও অসম্পূর্ণ এইচটিএমএলকে বিশ্লেষণ করে এবং এটি সত্যিই দুর্দান্ত।
শেষ

3

চেষ্টা করুন:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)

আপনি যদি সত্যিই এইচটিএমএল পার্সিংয়ের জন্য আরজিইএক্সএক্স ব্যবহার করতে চান তবে সরাসরি ম্যাচে .গ্রুপ () চালাবেন না, কারণ এটি কোনওটিই প্রত্যাবর্তন করতে পারে।
iElectric

ডকুমেন্টে .*?একাধিক থাকলে আপনার ব্যবহার করা উচিত </title>(সম্ভাব্য তবে আপনি কখনই জানেন না)।
টনফা

@ আই ইলেক্ট্রিক: আপনি যদি সত্যিই চান তবে ব্লক ব্যতীত চেষ্টা করে দেখতে পারেন, তাই না?
টনফা

3

প্রদত্ত কোডের টুকরোগুলি Exceptions আমি প্রস্তাব দিই না

getattr(re.search(r"<title>(.*)</title>", s, re.IGNORECASE), 'groups', lambda:[u""])()[0]

প্যাটার্নটি না পাওয়া গেলে বা প্রথম ম্যাচটি ডিফল্টরূপে এটি খালি স্ট্রিং দেয় returns


1

আমি মনে করি এটি যথেষ্ট হবে:

#!python
import re
pattern = re.compile(r'<title>([^<]*)</title>', re.MULTILINE|re.IGNORECASE)
pattern.search(text)

... ধরে নিচ্ছেন যে আপনার পাঠ্য (এইচটিএমএল) "পাঠ্য" নামের একটি ভেরিয়েবলে রয়েছে।

এটিও ধরে নিয়েছে যে এমন কোনও এইচটিএমএল ট্যাগ নেই যা আইনীভাবে এইচটিএমএল টাইটেল ট্যাগের অভ্যন্তরে এম্বেড করা যেতে পারে এবং এই জাতীয় ধারক / ব্লকের মধ্যে অন্য কোনও কোনও চরিত্রকে আইনীভাবে এম্বেড করার কোনও উপায় নেই।

তবে ...

পাইথনে HTML পার্সিংয়ের জন্য নিয়মিত এক্সপ্রেশন ব্যবহার করবেন না। এইচটিএমএল পার্সার ব্যবহার করুন! (আপনি যদি একটি সম্পূর্ণ পার্সার লিখতে যাচ্ছেন না, যা বিভিন্ন HTML, এসজিএমএল এবং এক্সএমএল পার্সারগুলি ইতিমধ্যে স্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে তখন অতিরিক্ত কাজ হয়ে যাবে।

আপনার হ্যান্ডলিং "বাস্তবিক পৃথিবীতে" যদি ট্যাগ স্যুপ এইচটিএমএল (যা ঘন ঘন কোনো যার SGML / এক্সএমএল যাচাইকারী অ অনুসারী থাকে) তাহলে ব্যবহার BeautifulSoup প্যাকেজ। এটি স্ট্যান্ডার্ড লাইব্রেরিতে নেই (এখনও) তবে এই লক্ষ্যে প্রশস্ত প্রস্তাব দেওয়া হয়েছে।

অন্য বিকল্পটি হ'ল: lxML ... যা সঠিকভাবে কাঠামোগত (স্ট্যান্ডার্ডস কনফর্মেন্ট ) এইচটিএমএল জন্য লেখা। তবে এতে পার্সার হিসাবে বিউটিফুলসপ ব্যবহার করার ক্ষেত্রে ফলব্যাক করার বিকল্প রয়েছে: এলিমেন্টসপ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.