2015-11-18 3 views
10

text:で始まる大括弧内のテキストのキャプチャで現在動作している正規表現/^\[(text:\s*.+?\s*)\]/miがあります。ここではそれが動作する例です。正規表現でいくつかの例外を除いて括弧内のテキストを検索するにはどうすればよいですか?

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

さて、私はそれが下の場合と同様に、特定のブラケットができますように例外を追加したいと思います:

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

は基本的に、私はそれができるようにする必要があります括弧内の括弧は![](/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) and some more text] 

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

![text: cat] 

ここでは、それが一致していなければならないいくつかの例です:

[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

これらの角かっこを特別なものにして、一致させる必要がありますか?それはその前の '!'ですか?それらが対応する開閉括弧であることは事実ですか?それらの括弧はより深くネストすることができますか? –

+0

正規表現の味は? –

+0

使用している[regex](https://en.m.wikipedia.org/wiki/Comparison_of_regular_expression_engines)の「味」を知る必要があります。 – binarysubstrate

答えて

6

OK、あなたが開始と終了のブラケットの間

  • ブラケットまたは
  • ない文字列![]

のいずれかを許可するようにします。

^   # 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 ] 

テストそれlive on regex101.com:これは、あなたの正規表現

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

説明を提供します。

^\[(text:.+?)(?<!\[)\] 
ここ

ウォークスルーです:

+1

正規表現で '.'を使わない場合、' m'識別子は必要ありません。これは、 '![](/ ''または '![]('' ' – sawa

+0

@sawa:ああ、Rubyでは 'ruby'タグが追加されました。幸運にも、'^'の意味はRubyではあいまいではありません:) –

0

私はあなたが次の正規表現を試すべきだと思います:

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

私は閉じ括弧がすぐに開きブラケットに従わないことを主張するために、この正規表現でnegative lookbehindを使用しました。

^   # 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. 

ここにはdemoがあります。

+0

Clever!' \ s * 'は何も追加しません。 –

+0

ニース;私はドキュメント/可読性のために冗長なPythonを使用しますが、それを行う方法がわかりませんでした(私の答えを見てください)。 Rubyで、不要な '\ s *'についての良い点 - 私は自分の答えを更新しました。 – binarysubstrate

+0

メンバーの名前がコメントにない場合、SOメンバーにはコメントが通知されません。 、@CarySwovelまたは@Caryだけ)。 –

3

新しい行の文字があなたの説明とどのように関係しているかわからないので、^を削除しました。

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

あなたの正規表現を使用できますが、少し修正されて簡略化されています。正規表現では、\s*.+?\s*は、あなたが、その場合、あなたは複数行モードを必要としない[^\]]+.+?を置き換えることができます(@sawaが述べたように).+?と同じであり、

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)] 

注意。

編集:OPの質問の編集に照らしてSUBSTITUTE_OUTを更新しました。これは、このアプローチの利点の1つを示しています。正規表現は、内側の一致するテキストの変更によって影響を受けません。

関連する問題