回答編集履歴

6

v0.2.1

2018/01/28 08:17

投稿

think49
think49

スコア18166

test CHANGED
@@ -124,9 +124,9 @@
124
124
 
125
125
 
126
126
 
127
- v0.1.0 は後読みを使用している為、Google Chrome 62 以上でなければ動作しません。
127
+ v0.1.1 は後読みを使用している為、Google Chrome 62 以上でなければ動作しません。
128
128
 
129
- v0.2.0 は後読みを使用せず、修飾子m(multiline)を使用しており、一般的なブラウザ全般で動作します。
129
+ v0.2.1 は後読みを使用せず、修飾子m(multiline)を使用しており、一般的なブラウザ全般で動作します。
130
130
 
131
131
  テキストエディタで動作させる場合は、multilineオプションに対応しているかどうかで使い分けるといいでしょう。
132
132
 

5

行末処理が不完全だった為、GitHubリンクを delete-duplicate-line-0.1.1.js, delete-duplicate-line-0.2.1.js に更新した

2018/01/28 08:17

投稿

think49
think49

スコア18166

test CHANGED
@@ -118,9 +118,9 @@
118
118
 
119
119
 
120
120
 
121
- - [delete-duplicate-line-0.1.0.js: GitHubGist](https://gist.github.com/think49/9ccf52aa1f2d01e4417b6f0fb2d37ce9/49bd739b83c5f33a280d65dab5e62edf83b353d5)
121
+ - [delete-duplicate-line-0.1.1.js - GitHubGist](https://gist.github.com/think49/9ccf52aa1f2d01e4417b6f0fb2d37ce9)
122
122
 
123
- - [delete-duplicate-line-0.2.0.js: GitHubGist](https://gist.github.com/think49/9ccf52aa1f2d01e4417b6f0fb2d37ce9)
123
+ - [delete-duplicate-line-0.2.1.js - GitHubGist](https://gist.github.com/think49/9ccf52aa1f2d01e4417b6f0fb2d37ce9)
124
124
 
125
125
 
126
126
 
@@ -164,6 +164,8 @@
164
164
 
165
165
  - 2018/01/28 14:19 「動作確認版1」に存在する問題点、動作確認版2、一番初めにマッチした重複行を残すには、を追記
166
166
 
167
+ - 2018/01/28 17:14 行末処理が不完全だった為、GitHubリンクを delete-duplicate-line-0.1.1.js, delete-duplicate-line-0.2.1.js に更新した
168
+
167
169
 
168
170
 
169
171
  Re: LUCIA さん

4

削除漏れ

2018/01/28 08:14

投稿

think49
think49

スコア18166

test CHANGED
@@ -17,10 +17,6 @@
17
17
 
18
18
 
19
19
  ### 動作確認版1 (前方一致で重複判定、一番最後の重複行を残す)
20
-
21
-
22
-
23
- **(追記)**
24
20
 
25
21
 
26
22
 

3

「動作確認版1」に存在する問題点、動作確認版2、一番初めにマッチした重複行を残すには、を追記

2018/01/28 05:20

投稿

think49
think49

スコア18166

test CHANGED
@@ -16,11 +16,11 @@
16
16
 
17
17
 
18
18
 
19
- ### 動作確認版
19
+ ### 動作確認版1 (前方一致で重複判定、一番最後の重複行を残す)
20
20
 
21
21
 
22
22
 
23
- **(2018/01/27 00:21追記)**
23
+ **(追記)**
24
24
 
25
25
 
26
26
 
@@ -58,4 +58,116 @@
58
58
 
59
59
 
60
60
 
61
+ ### 「動作確認版1」に存在する問題点
62
+
63
+
64
+
65
+
66
+
67
+ 今回は簡易的なサンプルであるが故に、比較的シンプルな正規表現となる事を目指しました。
68
+
69
+ あくまでもサンプルであり、叩き台にしてもらうべく書いた正規表現です。
70
+
71
+ 仮に、「私が考える実用的な正規表現を書くこと」を試みるならば、「動作確認版1」にはいくつかの問題があるので、私はこの問題の修正を試みます。
72
+
73
+
74
+
75
+ - (問題1) 文頭(`^`) にマッチした場合に末尾の `\n` が残る(一番初めに空行が一つ残る)
76
+
77
+ - (問題2) 前方一致で重複検索する (固定長文字列でなかった場合に誤爆する)
78
+
79
+ - (問題3) 前方から重複行を削除していき、最後に重複していない行を残す
80
+
81
+
82
+
83
+ (問題1) は「`^`で始まる行」と「`\n` で始まる行」を同一処理とし、`\n` の削除が「`\n` で始まる行」でしか行われない事に起因します。
84
+
85
+ 解決するには、「`^`で始まる行」と「`\n` で始まる行」を双方とも行末の `\n` を削除し、行頭の `\n` を削除しない方向に修正すれば良いでしょう。
86
+
87
+
88
+
89
+ (問題2) は例題がほぼ「固定長文字列」であった為、重複判定処理をさぼりました。
90
+
91
+ 具体的には、`@aa\n@aaa` の文字列に対して、`\n@aaa` を出力するという問題です。
92
+
93
+ `@aaa` は `@aa` で始まる為に重複判定が働いてしまいます。
94
+
95
+ 行末判定が疎かなので、しっかりと行末を先読みすればこの問題は回避できます。
96
+
97
+
98
+
99
+ (問題3) は私は問題とは認識していませんでした。
100
+
101
+ 要件では「重複行を削除する」としかなく、**「重複があった場合に、どの行を残すかまでは指定されていなかった」**からです。
102
+
103
+ 仮に一番初めにマッチした行を残す仕様とするならば、先読みの代わりに後読みを使う事で解決できるでしょう。
104
+
105
+
106
+
107
+ ### 動作確認版2 (完全一致で重複判定、一番最後の重複行を残す)
108
+
109
+
110
+
111
+ 次の修正を施したとします。
112
+
113
+
114
+
115
+ - (問題1), (問題2) を解消する
116
+
117
+ - (問題3) はそのまま残す
118
+
119
+
120
+
121
+ コードをGitHubにUPしました。
122
+
123
+
124
+
125
+ - [delete-duplicate-line-0.1.0.js: GitHubGist](https://gist.github.com/think49/9ccf52aa1f2d01e4417b6f0fb2d37ce9/49bd739b83c5f33a280d65dab5e62edf83b353d5)
126
+
127
+ - [delete-duplicate-line-0.2.0.js: GitHubGist](https://gist.github.com/think49/9ccf52aa1f2d01e4417b6f0fb2d37ce9)
128
+
129
+
130
+
131
+ v0.1.0 は後読みを使用している為、Google Chrome 62 以上でなければ動作しません。
132
+
133
+ v0.2.0 は後読みを使用せず、修飾子m(multiline)を使用しており、一般的なブラウザ全般で動作します。
134
+
135
+ テキストエディタで動作させる場合は、multilineオプションに対応しているかどうかで使い分けるといいでしょう。
136
+
137
+
138
+
139
+ ### 一番初めにマッチした重複行を残すには
140
+
141
+
142
+
143
+ (問題3) ですが、「一番初めにマッチした行を残す仕様」にする場合は先読みを後読みに変更する事で改善する案が想像できますが、これはかなり難易度が高いようです(私が「後読みに関して熟知していない」という理由もあります)。
144
+
145
+ 途中までは作成したので、興味がある方は挑んでみると面白いかもしれません。
146
+
147
+
148
+
149
+ ```JavaScript
150
+
151
+ 'use strict';
152
+
153
+ function deleteDuplicateLine (string) {
154
+
155
+ return string.replace(/(?<=(?:^|\r\n|[\n\r])(.+)(?:(?:\r\n|[\n\r])(?!\1[\n\r])(.*))*)(?:\r\n|[\n\r])\1(?=[\n\r]|$)/g, '');
156
+
157
+ }
158
+
159
+ ```
160
+
161
+
162
+
163
+ ### 更新履歴
164
+
165
+
166
+
167
+ - 2018/01/27 00:21 動作確認版1を追記
168
+
169
+ - 2018/01/28 14:19 「動作確認版1」に存在する問題点、動作確認版2、一番初めにマッチした重複行を残すには、を追記
170
+
171
+
172
+
61
173
  Re: LUCIA さん

2

一行ずつ照合していく

2018/01/28 05:19

投稿

think49
think49

スコア18166

test CHANGED
@@ -52,6 +52,8 @@
52
52
 
53
53
 
54
54
 
55
+ 一行ずつ照合していくという意味ではそうですね。
56
+
55
57
  テキストエディタの場合は「検索」と「置換」で文字列処理をしますので、重複削除するには空文字(`''`)に置換する事になります。
56
58
 
57
59
 

1

動作確認版

2018/01/26 15:26

投稿

think49
think49

スコア18166

test CHANGED
@@ -1,10 +1,14 @@
1
- 正規表現でも実装できますが、先読みのコストが高いのでお勧めはしません。
2
-
3
- 以下、未検証ですが、考え方の参考になれば。
1
+ ### 未検証
4
2
 
5
3
 
6
4
 
5
+ 正規表現でも実装できますが、先読みのコストが高いのでお勧めはしません。
6
+
7
+ ~~以下、未検証ですが、考え方の参考になれば。~~ (下記は期待通りに動きません)
8
+
9
+
10
+
7
- ```plain
11
+ ```JavaScript
8
12
 
9
13
  @(.*)(?:\n|$)(?=(?:@(?!\1\n).*\n)*(?!@\1(?:\n|$)))
10
14
 
@@ -12,4 +16,44 @@
12
16
 
13
17
 
14
18
 
19
+ ### 動作確認版
20
+
21
+
22
+
23
+ **(2018/01/27 00:21追記)**
24
+
25
+
26
+
27
+ 下記コードで期待通りに動作する事を確認しました。
28
+
29
+ mattnさんが掲示された事例にもマッチするよう、汎用的に行の重複削除するように(行頭が@で始まらなくても良い)書き直しました。
30
+
31
+
32
+
33
+ ```JavaScript
34
+
35
+ 'use strict';
36
+
37
+ var string = '@aaa\n@bbb\n@ccc\n@aaa\n@ddd\n@eee\n@aaa',
38
+
39
+ search = /(?:\n|^)(.*)(?=(?:\n(?!\1).*)*\n\1)/g,
40
+
41
+ replace = '';
42
+
43
+
44
+
45
+ console.log(string.replace(search, replace));
46
+
47
+ ```
48
+
49
+
50
+
51
+ > これは…順番に照合していって重複かどうか判断していくような構文でしょうか。
52
+
53
+
54
+
55
+ テキストエディタの場合は「検索」と「置換」で文字列処理をしますので、重複削除するには空文字(`''`)に置換する事になります。
56
+
57
+
58
+
15
59
  Re: LUCIA さん