2017-04-25 10 views
5

मैं उन जगहों से पहले तारों को विभाजित करने की कोशिश कर रहा हूं जहां एक पूरा स्थान है, सफेद स्थान से घिरा 2 अंक संख्या। आखिर में मैं इसे पायथन में काम करना चाहता हूं, लेकिन मैं sed के साथ काम कर रहा हूं और मैं इसे समझ नहीं सकता।मैं इस स्ट्रिंग को कैसे विभाजित कर सकता हूं?

मेरे परीक्षण डेटा इस तरह दिखता है:

13 13 13 13 13 9:07.18 9:12.09 9:15.65 
14 14 14 2:04.86 2:05.99 2:06.87 14 4:21.51 4:23.51 4:25.00 14 8:56.28 9:01.09 9:04.58 
15 15 57.18 57.61 57.95 15 2:02.61 2:03.72 2:04.58 15 4:17.31 4:19.28 4:20.75 15 8:47.15 8:51.87 8:55.30 
16 16 56.34 56.76 57.09 16 2:00.69 2:01.78 2:02.63 16 4:13.75 4:15.69 4:17.14 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99 17 55.62 56.03 56.36 17 1:59.07 2:00.15 2:00.99 17 4:10.76 4:12.69 4:14.11 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73 18 55.01 55.42 55.74 18 1:57.74 1:58.81 1:59.63 18 4:08.34 4:10.24 4:11.66 18 8:33.73 8:37.04 
19 25.20 25.36 25.49 19 54.50 54.91 55.23 19 1:57.74 1:58.56 19 4:08.34 4:09.74 19 8:33.73 

और मैं इसे इस तरह विभाजित किया जा चाहते हैं (टिप्पणी के लिए अल्पविराम का स्थान ','):

13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 
14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 
15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 
16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 
19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

उपर्युक्त डेटा, काफी नियमित है कि दो अंकों की पूरी संख्या सीमा [13,19] है, लेकिन मुझे जिस सीमा की अपेक्षा करनी चाहिए वह [10,99] है।

क्या कोई उपर्युक्त परिवर्तन करने के लिए एक विधि सुझा सकता है? मैं थोड़ी देर के लिए रेगेक्स के साथ इस पर रहा हूं लेकिन मैं सभी मामलों को कवर नहीं कर सकता हूं।

+0

stru क्या है आपके डेटा का इलाज? - यदि आपके पास 'स्ट्रिंग' में आपका डेटा है तो 'mydata = mydata.split ('') ' – GiantsLoveDeathMetal

+1

@GiantsLoveDeathMetal बस विभाजन करना ओपी चाहता है जो नहीं करता है। पहली पंक्ति के वांछित आउटपुट को देखें: ऐसा समय घटक जैसा दिखता है जिसे पिछले "तत्व" में पिछले पूर्णांक के रूप में रखा जाना चाहिए। – blacksite

+0

@not_a_robot हाँ - मुश्किल – GiantsLoveDeathMetal

उत्तर

7

लुक-आगे जोर (?=...) इस का समाधान कर सकते हैं:

>>> a = """13 13 13 13 13 9:07.18 9:12.09 9:15.65 
14 14 14 2:04.86 2:05.99 2:06.87 14 4:21.51 4:23.51 4:25.00 14 8:56.28 9:01.09 9:04.58 
15 15 57.18 57.61 57.95 15 2:02.61 2:03.72 2:04.58 15 4:17.31 4:19.28 4:20.75 15 8:47.15 8:51.87 8:55.30 
16 16 56.34 56.76 57.09 16 2:00.69 2:01.78 2:02.63 16 4:13.75 4:15.69 4:17.14 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99 17 55.62 56.03 56.36 17 1:59.07 2:00.15 2:00.99 17 4:10.76 4:12.69 4:14.11 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73 18 55.01 55.42 55.74 18 1:57.74 1:58.81 1:59.63 18 4:08.34 4:10.24 4:11.66 18 8:33.73 8:37.04 
19 25.20 25.36 25.49 19 54.50 54.91 55.23 19 1:57.74 1:58.56 19 4:08.34 4:09.74 19 8:33.73""" 

>>> print(re.sub("(\d{2}) (?=\d{2}(|$))","\g<1>, ", a)) 
13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 
14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 
15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 
16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 
19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

तो, reg exp। आप की जरूरत (\d{2}) (?=\d{2}(|$)) जिसका मतलब है कि है:

  1. (\d{2}) => स्टोर समूह 1 में 2 नंबर और एक अतिरिक्त स्थान से मेल खाते हैं।
  2. (?=\d{2}(|$)) => 2 नंबर और 1 स्थान या ईओएल मैच करें, लेकिन उनका उपभोग न करें।

यहां कुंजी यह है कि दूसरे मिलान किए गए समूह का उपभोग न करके, अगली बार उप फ़ंक्शन लागू होने पर इसे फिर से संसाधित किया जाएगा। अंत में, \g<1>, 1 को उसी नंबर और अतिरिक्त , के साथ प्रतिस्थापित करेगा।

+2

कृपया अपने regex को समझाएं :) – GiantsLoveDeathMetal

+0

@GiantsLoveDeathMetal कृपया मुझे बताएं कि आपको किसी अतिरिक्त स्पष्टीकरण की आवश्यकता है :) – VMRuiz

+0

यह अच्छा है - – GiantsLoveDeathMetal

0

sed के मजे के लिए और क्योंकि आप समझने के लिए एक रेड संदर्भ में रुचि रखते हैं।

sed ":a;s/\([^,]\)\(\s[0-9]\{2\}\s\)/\1,\2/;ta" 

या

sed -E ":a;s/([^,])(\s[0-9]{2}\s)/\1,\2/;ta" 
    एक पाश के लिए
    • बाद में पाशन
    • एक के लिए , से कुछ अन्य, महत्वपूर्ण
      • नज़र शुरू
      • खाली स्थान के दो अंक है और एक खाली स्थान के
    • गैर अल्पविराम, एक अल्पविराम और बाकी
  • पाश द्वारा की जगह है कि अगर कुछ बदल दिया

आउटपुट (वास्तव में वांछित आउटपुट के रूप में):

13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 
14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 
15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 
16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 
19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 
+0

बहुत अच्छा। बस सोच रहा है, क्या आप विस्तारित regex का उपयोग करके कुछ बैकस्लाश से छुटकारा पा सकते हैं? – wjandrea

+0

@wjandrea हां, संपादन देखें। – Yunnosch

0

VMRuiz's answer को जोड़ना, इस आउटपुट एक एक बड़ी स्ट्रिंग के बजाय प्रत्येक पंक्ति के लिए सूची। re.sub के बजाय re.split का उपयोग करने के लिए मुझे रेगेक्स को बदलना पड़ा, और मुझे यकीन नहीं है कि यह बराबर है।

for line in a.split('\n'): 
    re.split('(?<=\d{2}) (?=\d{2} |$)', line) 

संपादित करें: यह निश्चित रूप से एक ही है, लेकिन थोड़ा अजीब:

for line in re.sub('(\d{2}) (?=\d{2}(|$))', '\g<1>,', a).split('\n'): 
    line.split(',') 
0

आप एक गैर regex अजगर समाधान चाहते हैं, तो आप कर सकते हैं:

s = """\ 
13 13 13 13 13 9:07.18 9:12.09 9:15.65 
14 14 14 2:04.86 2:05.99 2:06.87 14 4:21.51 4:23.51 4:25.00 14 8:56.28 9:01.09 9:04.58 
15 15 57.18 57.61 57.95 15 2:02.61 2:03.72 2:04.58 15 4:17.31 4:19.28 4:20.75 15 8:47.15 8:51.87 8:55.30 
16 16 56.34 56.76 57.09 16 2:00.69 2:01.78 2:02.63 16 4:13.75 4:15.69 4:17.14 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99 17 55.62 56.03 56.36 17 1:59.07 2:00.15 2:00.99 17 4:10.76 4:12.69 4:14.11 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73 18 55.01 55.42 55.74 18 1:57.74 1:58.81 1:59.63 18 4:08.34 4:10.24 4:11.66 18 8:33.73 8:37.04 
19 25.20 25.36 25.49 19 54.50 54.91 55.23 19 1:57.74 1:58.56 19 4:08.34 4:09.74 19 8:33.73""" 


res="" 
for line in s.splitlines(): 
    buf=line.split() 
    for i, e in enumerate(buf[1:], 1): 
     buf[i-1]+=", " if e.isdigit() else " " 
    res+=''.join(buf)+"\n" 

>>> res 
13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 
14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 
15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 
16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 
19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 

awk में आप कर सकते हैं:

awk '{n=split($0,a) 
     for (i=2;i<=n;i++) 
      printf "%s%s", a[i-1], a[i]~/^[[:digit:]]+$/ ? ", " : " " 
     print a[n] 
    }' file 
13, 13, 13, 13, 13 9:07.18 9:12.09 9:15.65 
14, 14, 14 2:04.86 2:05.99 2:06.87, 14 4:21.51 4:23.51 4:25.00, 14 8:56.28 9:01.09 9:04.58 
15, 15 57.18 57.61 57.95, 15 2:02.61 2:03.72 2:04.58, 15 4:17.31 4:19.28 4:20.75, 15 8:47.15 8:51.87 8:55.30 
16, 16 56.34 56.76 57.09, 16 2:00.69 2:01.78 2:02.63, 16 4:13.75 4:15.69 4:17.14, 16 8:39.71 8:44.37 8:47.75 
17 25.69 25.85 25.99, 17 55.62 56.03 56.36, 17 1:59.07 2:00.15 2:00.99, 17 4:10.76 4:12.69 4:14.11, 17 8:33.73 8:38.34 8:41.68 
18 25.43 25.59 25.73, 18 55.01 55.42 55.74, 18 1:57.74 1:58.81 1:59.63, 18 4:08.34 4:10.24 4:11.66, 18 8:33.73 8:37.04 
19 25.20 25.36 25.49, 19 54.50 54.91 55.23, 19 1:57.74 1:58.56, 19 4:08.34 4:09.74, 19 8:33.73 
संबंधित मुद्दे

 संबंधित मुद्दे