2015-11-18 17 views
10

Şu anda text: ile başlayan parantez içinde metin yakalama konusunda çalışan bir regex /^\[(text:\s*.+?\s*)\]/mi var. Şöyle çalışır bir örnek: aşağıda durumda gibi bazı ayraçlar verir, böyleceDüzenli ifadelere göre bazı istisnalarla parantez içinde metin nasıl bulunur?

[text: here is my text that is 
captured within the brackets.] 

Şimdi, bir istisna eklemek istiyorum: Temelde

[text: here is my text that is 
captured within the brackets 
and also include ![](/some/path)] 

, ben izin vermesini sağlamak için ihtiyaç eşleşmedeki ![](/some/path) parantezleri.

Herhangi bir yardım büyük memnuniyetle karşılanacaktır. Teşekkürler.

Güncelleme: İşte

[text: here is my text that is 
captured within the brackets 
and also include ![](/some/path)] 

[text: here is my text that is 
captured within the brackets 
and also include ![](/some/path) and some more text] 

[text: ![](/some/path)] 

![text: cat] 

o eşleşmiyor gereken bazı durumlar vardır: İşte

parantez içindeki metin uydurulması gereken bazı durumlar vardır

[text: here is my text that is 
captured within the brackets 
and also include ![invalid syntax](/some/path)] 

[text: here is my text that is 
captured within the brackets 
and also include ![] (/some/path)] 

[text: here is my text that is 
captured within the brackets 
and also include ! [](/some/path)] 

[text: here is my text that is 
captured within the brackets 
and also include ! [] (/some/path)] 
+3

Bu köşeli ayraçlar tam olarak eşleştirilmeleri gereken şey nedir? Onlardan önce mi? Açılış/kapanış parantezlerine uygun olmaları mı? Bu parantez daha derinlemesine iç içe olabilir mi? –

+0

Normal ifadeler nelerdir? –

+0

Kullanmakta olduğunuz [regex] 'in ("https://en.m.wikipedia.org/wiki/Comparison_of_regular_expression_engines") "lezzetini" bilmemiz gerekiyor. – binarysubstrate

cevap

6

Tamam, izin vermek istediğiniz ya

  • bir ayraç veya
  • dizisi başlangıç ​​ve bitiş braket arasında ![]

olmayan bir karakter.

^   # Start of line 
\[   # Match [ 
(   # Start of capturing group 
text:  # Match text: 
[^\[\]]* # Match any number of characters except [ or ] 
(?:  # Optional non-capturing group: 
    !\[\]  # Match ![] 
    [^\[\]]* # Match any number of characters except [ or ] 
)*   # Repeat as needed (0 times is OK) 
)   # End of capturing group 
\]   # Match ] 

Testi o live on regex101.com: RegEx'in size

/^\[(text:[^\[\]]*(?:!\[\][^\[\]]*)*)\]/mi 

Açıklama verir.

^\[(text:.+?)(?<!\[)\] 
İşte

adım adım açıklanmıştır:

+1

İntikamında' .' kullanmıyorsanız, 'm' tanımlayıcısına ihtiyacınız yoktur. – sawa

+0

@sawa: Ah, 'ruby' etiketi cevabımdan sonra eklendi. Neyse ki,'^'in anlamı Ruby'de belirsizdir :) –

0

Aşağıdaki regex'i denemeniz gerektiğini düşünüyorum:

^\[(text:.*?(?<!\[))\] 
3

Ben bir kapanış braket hemen bir açılış ayracı takip etmez iddia etmek bu regex bir negative lookbehind kullandım.

^   # Start of line anchor. 
\[   # Match opening bracket '[' 
(   # Start capturing group 1. 
text:  # Match 'text:' 
.+?   # Match any character one or more times lazily. 
)   # End capturing group 1. 
(?<!  # Begin negative lookbehind. 
\[   # '[' must not preceed the next match. 
)   # End negative lookbehind. 
\]   # Match closing bracket. 

İşte bir demo.

+0

Zeki!' \ S * 'bir şey eklemediğini unutmayın. genişletilmiş modda regex (cevabıma bakın) kendinizi tekrarlamak zorunda kalmazsınız (genişletilmiş modun her zaman kullanılamayacağını farketmez) –

+0

Güzel; belgeleme/okunabilirlik için ayrıntılı Python kullanıyorum, ancak nasıl yapılacağından emin değildim Ruby'de ve gereksiz hakkında iyi bir nokta '' '' - Cevaplarımı güncelledim – binarysubstrate

+0

Üye isminin yorumda bulunmaması durumunda SO üyelerine kendilerine yönlendirilen yorumların bildirilmediğini unutmayın (örn. , @CarySwoveland veya sadece @Cary). –

3

Yeni çizgi karakterinin açıkladığınızla ilgili olduğunu anlamıyorum, bu yüzden ^ kaldırdım.

/\[(text:(?:[^\[\]]|!\[\][/\w]+)+)\]/i 
4

Düzenli, biraz değiştirilmiş ve basitleştirilmiş kullanabilirsiniz.regex, \s*.+?\s* sen bu durumda satırlı modunu gerek olmazdı [^\]]+ ile .+? yerini alabilir (@sawa belirtildiği gibi) .+? ve aynıdır,

str =<<_ 
[text: here is my text that is 
captured within the brackets 
and also includes ![](/some/path)] 
and other stuff 
_ 

r =/
    ^  # match beginning of string 
    \[text: # match string 
    .+?  # match one or more characters lazily 
    \]  # match right bracket 
    /imx  # case indifferent (i), multiline (m) and extended/free-spacing (x) modes 

PLACEHOLDER = 0.chr 
SUBSTITUTE_OUT = '![](/' 

puts str.gsub(SUBSTITUTE_OUT, PLACEHOLDER). 
    scan(r). 
    map { |s| s.gsub(PLACEHOLDER, SUBSTITUTE_OUT) } 

[text: here is my text that is 
captured within the brackets 
and also includes ![](/some/path)] 

Not.

Düzeltme: Bu sorunun OP düzenlemesinin ışığında SUBSTITUTE_OUT güncelleştirildi. Bu, bu yaklaşımın bir avantajını gösterir: regex, iç eşleşen metindeki değişikliklerden etkilenmez.

İlgili konular