回答編集履歴
5
もういやだ(書式ミス)
answer
CHANGED
@@ -126,11 +126,7 @@
|
|
126
126
|
-----------------
|
127
127
|
本回答に辿り着く際に参照したリソース。
|
128
128
|
|
129
|
-
- [正規表現で文字列を含まない、否定の記述 ](https://uxmilk.jp/50674) - uxmilk.jp
|
129
|
+
- [正規表現で文字列を含まない、否定の記述 ](https://uxmilk.jp/50674) - uxmilk.jp - 否定の指定方法
|
130
|
-
- 否定の指定方法
|
131
|
-
- [正規表現の構造化および処理(マッチ・グループ・キャプチャ)](https://smdn.jp/programming/netfx/regex/1_operations/) - smdn.jp
|
130
|
+
- [正規表現の構造化および処理(マッチ・グループ・キャプチャ)](https://smdn.jp/programming/netfx/regex/1_operations/) - smdn.jp - グループ化の方法
|
132
|
-
- グループ化の方法
|
133
|
-
- サクラエディタ→検索(Ctrl+F)→ヘルプ→「正規表現」
|
134
|
-
|
131
|
+
- サクラエディタ→検索(Ctrl+F)→ヘルプ→「正規表現」- 正規表現のおおまかな機能と記法(注意:サクラエディタ限定のものもある)
|
135
|
-
- [正規表現言語 - クイック リファレンス](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-language-quick-reference) - docs.microsoft.com
|
132
|
+
- [正規表現言語 - クイック リファレンス](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-language-quick-reference) - docs.microsoft.com - 説明が複雑奇怪すぎるので、サクラエディタのヘルプとクロスリファレンス
|
136
|
-
- 説明が複雑奇怪すぎるので、サクラエディタのヘルプとクロスリファレンス
|
4
忘れ去られてた参考文献(わすれてない)
answer
CHANGED
@@ -120,4 +120,17 @@
|
|
120
120
|
Assert.AreEqual(sbCorrect.ToString(), text);
|
121
121
|
}
|
122
122
|
|
123
|
-
```
|
123
|
+
```
|
124
|
+
|
125
|
+
参考文献
|
126
|
+
-----------------
|
127
|
+
本回答に辿り着く際に参照したリソース。
|
128
|
+
|
129
|
+
- [正規表現で文字列を含まない、否定の記述 ](https://uxmilk.jp/50674) - uxmilk.jp
|
130
|
+
- 否定の指定方法
|
131
|
+
- [正規表現の構造化および処理(マッチ・グループ・キャプチャ)](https://smdn.jp/programming/netfx/regex/1_operations/) - smdn.jp
|
132
|
+
- グループ化の方法
|
133
|
+
- サクラエディタ→検索(Ctrl+F)→ヘルプ→「正規表現」
|
134
|
+
- 正規表現のおおまかな機能と記法(注意:サクラエディタ限定のものもある)
|
135
|
+
- [正規表現言語 - クイック リファレンス](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-language-quick-reference) - docs.microsoft.com
|
136
|
+
- 説明が複雑奇怪すぎるので、サクラエディタのヘルプとクロスリファレンス
|
3
実装1のリテラルを実装2と形式を合わせて違いがわかる?ように修正
answer
CHANGED
@@ -29,14 +29,20 @@
|
|
29
29
|
var expressionUrlGroup = "(?<url>" + expressionUrl + ")";
|
30
30
|
|
31
31
|
// 正規表現 URLのみ: 正規表現の前方否定戻り読み「(?<!~)」でカッコやダブルクォーテーションがマッチしないようにする
|
32
|
-
var
|
32
|
+
var expressionUrlOnly = "(?<![\(\\"]\s*)" + expressionUrlGroup + "(?!\s*[\)\\"])";
|
33
|
-
|
33
|
+
// ^^^^^^^ カッコやダブルクォーテーション
|
34
|
-
|
34
|
+
// ^^^^ スペースを入れた場合の考慮
|
35
|
+
|
36
|
+
// 正規表現 マークダウン
|
37
|
+
var expressionMarkdown = "\[(?<text>[^\]]*)\]\(\s*" + expressionUrlGroup + "\s*\)";
|
38
|
+
|
39
|
+
// 正規表現 URLのみ
|
40
|
+
var regexUrlOnly = new Regex(expressionUrlOnly,
|
35
41
|
RegexOptions.IgnoreCase // 大文字小文字を区別しない
|
36
42
|
| RegexOptions.Compiled // コンパイルする(この正規表現を使いまわす場合)
|
37
43
|
);
|
38
44
|
// 正規表現 マークダウン
|
39
|
-
var regexMarkdown = new Regex(
|
45
|
+
var regexMarkdown = new Regex(expressionMarkdown,
|
40
46
|
RegexOptions.IgnoreCase // 大文字小文字を区別しない
|
41
47
|
| RegexOptions.Compiled // コンパイルする(この正規表現を使いまわす場合)
|
42
48
|
);
|
2
実装2のコメント誤りを修正
answer
CHANGED
@@ -87,7 +87,6 @@
|
|
87
87
|
// 正規表現 全て
|
88
88
|
var expressonAll = "(" + expressionUrlOnly + ")|(" + expressionMarkdown + ")";
|
89
89
|
|
90
|
-
// 正規表現 URLのみ: 正規表現の前方否定戻り読み「(?<!~)」でカッコやダブルクォーテーションがマッチしないようにする
|
91
90
|
var regexUrl = new Regex(expressonAll,
|
92
91
|
RegexOptions.IgnoreCase // 大文字小文字を区別しない
|
93
92
|
| RegexOptions.Compiled // コンパイルする(この正規表現を使いまわす場合)
|
1
URLの正規表現を変更
answer
CHANGED
@@ -16,7 +16,6 @@
|
|
16
16
|
単体テスト形式で回答いたします。
|
17
17
|
なお、XSS等の考慮はしていないので、ご注意ください。
|
18
18
|
|
19
|
-
#なぜか、実装2のほうが100ms実行時間が長かった。理由は調べていないので、言及できません。
|
20
19
|
|
21
20
|
実装例1: 2段階で置換を行うパターン
|
22
21
|
-------------------------
|
@@ -24,25 +23,7 @@
|
|
24
23
|
[TestMethod]
|
25
24
|
public void TestTeratail356904_1()
|
26
25
|
{
|
27
|
-
var expressionUrl = "https?:
|
28
|
-
// ログイン関連
|
29
|
-
+ "((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|:)*@)?"
|
30
|
-
// ホスト名/IPv4/6
|
31
|
-
+ "(\[((([0-9a-f]{1,4}:){6}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
32
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|::([0-9a-f]{1,4}:){5}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
33
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|([0-9a-f]{1,4})?::([0-9a-f]{1,4}:){4}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
34
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){3}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
35
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){2}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
36
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
37
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
38
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(([0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)"
|
39
|
-
+ "|v[0-9a-f]+\.(([a-z]|[0-9]|[-._~])|[!$&'()*+,;=]|:)+)]|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
40
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}|(([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=])*)(:\d*)?"
|
41
|
-
// スラッシュ以降
|
42
|
-
+ "(\/((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|[:@]))*)*"
|
43
|
-
+ "(\?((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|[:@])|[\/?])*)?"
|
44
|
-
+ "(#((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|[:@])|[\/?])*)?"
|
45
|
-
; // from https://qiita.com/shimataro999/items/fced9665fa970c009c1e
|
26
|
+
var expressionUrl = "s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+";
|
46
27
|
|
47
28
|
// グループ化(置換でこの部分を抜き出すため)
|
48
29
|
var expressionUrlGroup = "(?<url>" + expressionUrl + ")";
|
@@ -90,25 +71,7 @@
|
|
90
71
|
[TestMethod]
|
91
72
|
public void TestTeratail356904_2()
|
92
73
|
{
|
93
|
-
var expressionUrl = "https?:
|
94
|
-
// ログイン関連
|
95
|
-
+ "((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|:)*@)?"
|
96
|
-
// ホスト名/IPv4/6
|
97
|
-
+ "(\[((([0-9a-f]{1,4}:){6}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
98
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|::([0-9a-f]{1,4}:){5}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
99
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|([0-9a-f]{1,4})?::([0-9a-f]{1,4}:){4}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
100
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){3}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
101
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){2}([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
102
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
103
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:[0-9a-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
104
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(([0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)"
|
105
|
-
+ "|v[0-9a-f]+\.(([a-z]|[0-9]|[-._~])|[!$&'()*+,;=]|:)+)]|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
106
|
-
+ "(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}|(([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=])*)(:\d*)?"
|
107
|
-
// スラッシュ以降
|
108
|
-
+ "(\/((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|[:@]))*)*"
|
109
|
-
+ "(\?((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|[:@])|[\/?])*)?"
|
110
|
-
+ "(#((([a-z]|[0-9]|[-._~])|%[0-9a-f][0-9a-f]|[!$&'()*+,;=]|[:@])|[\/?])*)?"
|
111
|
-
; // from https://qiita.com/shimataro999/items/fced9665fa970c009c1e
|
74
|
+
var expressionUrl = "s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+";
|
112
75
|
|
113
76
|
// グループ化(置換でこの部分を抜き出すため)
|
114
77
|
var expressionUrlGroup = "(?<url>" + expressionUrl + ")";
|