পাঠ্যের একাধিক ব্লকের সাথে মিলে যাওয়া নিয়মিত প্রকাশ


108

একাধিক লাইন বিস্তৃত পাঠ্যের বিপরীতে মিলে যাওয়ার সময় পাইথন রেজেক্সটি কাজ করতে আমার কিছুটা সমস্যা হচ্ছে। উদাহরণ পাঠ্যটি ('\ n' একটি নতুন লাইন)

some Varying TEXT\n
\n
DSJFKDAFJKDAFJDSAKFJADSFLKDLAFKDSAF\n
[more of the above, ending with a newline]\n
[yep, there is a variable number of lines here]\n
\n
(repeat the above a few hundred times).

আমি দুটি জিনিস ক্যাপচার করতে চাই: 'কিছু_ভরিয়িং_একটি' অংশ, এবং বড় হাতের লেখার সমস্ত লাইন যা তার নীচে দুটি লাইনে আসে একটি ক্যাপচারে (আমি পরে নতুন লাইনের চরিত্রগুলি বের করতে পারি)। আমি কয়েকটি পদ্ধতির সাথে চেষ্টা করেছি:

re.compile(r"^>(\w+)$$([.$]+)^$", re.MULTILINE) # try to capture both parts
re.compile(r"(^[^>][\w\s]+)$", re.MULTILINE|re.DOTALL) # just textlines

এবং এর সাথে অনেক ভাগ্য নেই ভাগ্যের সাথে। শেষটি একের পর এক পাঠ্যের লাইনের সাথে মিলছে বলে মনে হচ্ছে যা আমি সত্যিই চাই না। আমি প্রথম অংশটি ধরতে পারি, কোনও সমস্যা নেই, তবে আমি বড় আকারের পাঠ্যের 4-5 লাইন ধরতে পারি না। খালি লাইন না আসা পর্যন্ত আমি ম্যাচ.group (1) কে কিছু_ভরিয়িং_টেক্সট এবং গোষ্ঠী (2) লাইন 1 + লাইন 2 + লাইন 3 + ইত্যাদি হতে চাই।

যদি কারও কৌতূহল হয়, তবে এটি অ্যামিনোসাইডগুলির ক্রম যা প্রোটিন তৈরি করে।


প্রথম লাইন এবং বড় হাতের লেখার পাশাপাশি ফাইলে কি অন্য কিছু আছে? আমি নিশ্চিত নই আপনি কেন নতুন পাঠ্য অক্ষরে সমস্ত পাঠ্য বিভক্ত করার পরিবর্তে এবং প্রথম উপাদানটিকে "কিছু_ভরিয়িং_একটি" হিসাবে গ্রহণ করার পরিবর্তে আপনি একটি রেজেক্স ব্যবহার করবেন I'm
আঙ্কেলজিভ

4
হ্যাঁ, রেজেক্স এটির জন্য ভুল সরঞ্জাম।

আপনার নমুনা পাঠ্যের একটি শীর্ষস্থানীয় >অক্ষর নেই। এটি করা উচিত?
MiniQuark

উত্তর:


116

এটা চেষ্টা কর:

re.compile(r"^(.+)\n((?:\n.+)+)", re.MULTILINE)

আমার মনে হয় আপনার সবচেয়ে বড় সমস্যাটি হ'ল আপনি ^এবং $অ্যাঙ্গারদের লাইনফিডগুলির সাথে মিল রাখার প্রত্যাশা করছেন , তবে তারা তা করেন না। মাল্টলাইন মোডে, একটি নিউলাইন অনুসরণ করার সাথে^ সাথেই অবস্থানের সাথে মেলে এবং তাত্ক্ষণিকভাবে একটি নতুন লাইনের আগের অবস্থানের সাথে মেলে ।$

এও সচেতন থাকুন যে একটি নতুন লাইনটিতে লাইনফিড (\ n), ক্যারিজ-রিটার্ন (\ r), বা ক্যারেজ-রিটার্ন + লাইনফিড (\ r \ n) থাকতে পারে। যদি আপনি নিশ্চিত না হন যে আপনার টার্গেট পাঠ্যটি কেবলমাত্র লাইনফিড ব্যবহার করে তবে আপনার রেজিএক্সের আরও অন্তর্ভুক্ত সংস্করণটি ব্যবহার করা উচিত:

re.compile(r"^(.+)(?:\n|\r\n?)((?:(?:\n|\r\n?).+)+)", re.MULTILINE)

বিটিডাব্লু, আপনি এখানে ডটল সংশোধক ব্যবহার করতে চান না; আপনি এই সত্যের উপর নির্ভর করছেন যে নিউলাইনগুলি বাদ দিয়ে বিন্দুটি সমস্ত কিছুর সাথে মেলে ।


আপনি যদি এই নিয়মিত এক্সপ্রেশনটি খালি দ্বিতীয় লাইনের সাথে কোনও পাঠ্য ফাইলের সাথে কেবল মিল না করতে চান তবে আপনি [এজেড] দ্বারা রেজিজেজের দ্বিতীয় বিন্দুটি প্রতিস্থাপন করতে চাইতে পারেন। ;-)
MiniQuark

আমার ধারণাটি হ'ল টার্গেট ফাইলগুলি খালি বনাম খালি লাইনগুলির একটি নির্দিষ্ট (এবং পুনরাবৃত্তি) প্যাটার্নার সাথে সামঞ্জস্য করবে, সুতরাং [এজেড] নির্দিষ্ট করার প্রয়োজন হবে না, তবে এটি সম্ভবত আঘাত করবে না।
অ্যালান মুর 21

এই সমাধানটি সুন্দরভাবে কাজ করেছে। একদিকে যেমন আমি ক্ষমাপ্রার্থী, যেহেতু আমি স্পষ্টতই পরিস্থিতিটি যথেষ্ট পরিমাণে স্পষ্ট করেছিলাম না (এবং এই জবাবটির দীর্ঘসূত্রতার জন্যও)। আপনার সাহায্যের জন্য ধন্যবাদ!
জানুয়ারী

24

এটি কাজ করবে:

>>> import re
>>> rx_sequence=re.compile(r"^(.+?)\n\n((?:[A-Z]+\n)+)",re.MULTILINE)
>>> rx_blanks=re.compile(r"\W+") # to remove blanks and newlines
>>> text="""Some varying text1
...
... AAABBBBBBCCCCCCDDDDDDD
... EEEEEEEFFFFFFFFGGGGGGG
... HHHHHHIIIIIJJJJJJJKKKK
...
... Some varying text 2
...
... LLLLLMMMMMMNNNNNNNOOOO
... PPPPPPPQQQQQQRRRRRRSSS
... TTTTTUUUUUVVVVVVWWWWWW
... """
>>> for match in rx_sequence.finditer(text):
...   title, sequence = match.groups()
...   title = title.strip()
...   sequence = rx_blanks.sub("",sequence)
...   print "Title:",title
...   print "Sequence:",sequence
...   print
...
Title: Some varying text1
Sequence: AAABBBBBBCCCCCCDDDDDDDEEEEEEEFFFFFFFFGGGGGGGHHHHHHIIIIIJJJJJJJKKKK

Title: Some varying text 2
Sequence: LLLLLMMMMMMNNNNNNNOOOOPPPPPPPQQQQQQRRRRRRSSSTTTTTUUUUUVVVVVVWWWWWW

এই নিয়মিত প্রকাশ সম্পর্কে কিছু ব্যাখ্যা কার্যকর হতে পারে: ^(.+?)\n\n((?:[A-Z]+\n)+)

  • প্রথম অক্ষর ( ^) এর অর্থ "একটি লাইনের শুরুতে শুরু করা"। সচেতন থাকুন যে এটি নিজেই নতুন লাইনের সাথে মেলে না (এটির জন্য same: এর অর্থ "একটি নতুন লাইনের ঠিক আগে", তবে এটি নিজেই নতুন লাইনের সাথে মেলে না)।
  • তারপরে (.+?)\n\n"যতক্ষণ না আপনি দুটি নতুন লাইনে পৌঁছাবেন ততক্ষণ" যতটা সম্ভব অক্ষরের সাথে মিলিত হোন (সমস্ত অক্ষরের অনুমতি রয়েছে) "means ফলাফল (নিউলাইনগুলি ছাড়াই) প্রথম গ্রুপে রাখা হয়েছে।
  • [A-Z]+\nমানে "যতক্ষণ না আপনি নতুন লাইনে পৌঁছাবেন তত বেশি আপার কেস চিঠিগুলি মিলিয়ে দিন This এটি আমি কী একটি পাঠ্যরেখাকে কল করব তা নির্ধারণ করে ।
  • ((?:পাঠ্যলাইনটির)+) অর্থ এক বা একাধিক পাঠ্যলাইনের সাথে মিল থাকলেও প্রতিটি লাইনে একটি গ্রুপে রাখবেন না। পরিবর্তে, করা সব textlines এক দলের।
  • আপনি \nযদি শেষে ডাবল নিউলাইন প্রয়োগ করতে চান তবে আপনি নিয়মিত অভিব্যক্তিটিতে একটি ফাইনাল যুক্ত করতে পারেন।
  • এছাড়াও, আপনি কি নিশ্চিত সম্পর্কে সম্পর্কে newline কি ধরনের আপনি পাবেন (না যদি \nবা \rবা \r\n) তারপর প্রতিটি সংঘটন প্রতিস্থাপন রেগুলার এক্সপ্রেশন ঠিক \nদ্বারা (?:\n|\r\n?)

4
ম্যাচ () লক্ষ্য পাঠ্যের একেবারে শুরুতে কেবল একটি ম্যাচ ফেরায়, তবে ওপি জানিয়েছে যে ফাইলটিতে প্রতি শত শত ম্যাচ থাকবে। আমি মনে করি আপনি পরিবর্তে সন্ধানকারী () চাইবেন।
অ্যালান মুর

6

যদি প্রতিটি ফাইলের এমিনোঅ্যাসিডগুলির কেবল একটি ক্রম থাকে তবে আমি কোনওমতেই নিয়মিত অভিব্যক্তি ব্যবহার করতাম না। এরকম কিছু:

def read_amino_acid_sequence(path):
    with open(path) as sequence_file:
        title = sequence_file.readline() # read 1st line
        aminoacid_sequence = sequence_file.read() # read the rest

    # some cleanup, if necessary
    title = title.strip() # remove trailing white spaces and newline
    aminoacid_sequence = aminoacid_sequence.replace(" ","").replace("\n","")
    return title, aminoacid_sequence

যদি কেবলমাত্র একটিই ছিল তবে এটি আরও কার্যকর হবে, যদি আরও কিছু যুক্তি যুক্ত হয় তবে অবশ্যই এটি সবচেয়ে সহজ উপায়। যদিও এই নির্দিষ্ট ডেটাসেটে প্রায় 885 টি প্রোটিন রয়েছে এবং আমি অনুভব করেছি যে একটি রেজেক্স এটি হ্যান্ডেল করতে সক্ষম হবে।
জানুয়ারী

4

অনুসন্ধান:

^>([^\n\r]+)[\n\r]([A-Z\n\r]+)

\ 1 = কিছু_ভরিয়িং_টেক্সট

C 2 = সমস্ত সিএপিএসের লাইন

সম্পাদনা করুন (প্রমাণ করে যে এটি কাজ করে):

text = """> some_Varying_TEXT

DSJFKDAFJKDAFJDSAKFJADSFLKDLAFKDSAF
GATACAACATAGGATACA
GGGGGAAAAAAAATTTTTTTTT
CCCCAAAA

> some_Varying_TEXT2

DJASDFHKJFHKSDHF
HHASGDFTERYTERE
GAGAGAGAGAG
PPPPPAAAAAAAAAAAAAAAP
"""

import re

regex = re.compile(r'^>([^\n\r]+)[\n\r]([A-Z\n\r]+)', re.MULTILINE)
matches = [m.groups() for m in regex.finditer(text)]

for m in matches:
    print 'Name: %s\nSequence:%s' % (m[0], m[1])

দুর্ভাগ্যক্রমে, এই নিয়মিত অভিব্যক্তি খালি রেখার দ্বারা পৃথক করা মূল অক্ষরের গোষ্ঠীর সাথেও মিলবে। যদিও এটি বড় কথা নাও হতে পারে।
MiniQuark

দেখে মনে হচ্ছে কুনজ FASTA ফাইল পছন্দ করে। ;)
অ্যান্ড্রু ডালকে

4

নীচে পাঠ্যের একটি বহুমাত্রিক ব্লকের সাথে মেলে নিয়মিত প্রকাশ:

import re
result = re.findall('(startText)(.+)((?:\n.+)+)(endText)',input)

1

আমার পছন্দ।

lineIter= iter(aFile)
for line in lineIter:
    if line.startswith( ">" ):
         someVaryingText= line
         break
assert len( lineIter.next().strip() ) == 0
acids= []
for line in lineIter:
    if len(line.strip()) == 0:
        break
    acids.append( line )

এই মুহুর্তে আপনার কাছে স্ট্রিং হিসাবে কিছুটা ভার্যিংটেক্সট রয়েছে, এবং এসিডগুলি স্ট্রিংগুলির একটি তালিকা হিসাবে। আপনি "".join( acids )একটি একক স্ট্রিং তৈরি করতে পারেন ।

আমি মাল্টলাইন রেজেক্সগুলির চেয়ে এটি হতাশ (এবং আরও নমনীয়) পেয়েছি।

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