String.prototype.replace
String.prototype.replace
の第二引数に関数を指定して分岐処理すれば良いと思います。
JavaScript
1 < script >
2 'use strict' ;
3 function addClassByStartTag ( startTag , token /* [...token] */ ) {
4 if ( arguments . length < 2 ) {
5 return startTag ;
6 }
7
8 startTag = / ^(<\w+)((\s[^>]*class\s*=\s*")([^"]*)("[^>]*>)|[^>]*>)$ / . exec ( startTag ) ;
9
10 if ( startTag [ 3 ] ) {
11 var tokens = startTag [ 4 ] . trim ( ) . split ( / \s+ / ) ;
12
13 for ( var i = 1 , l = arguments . length ; i < l ; ++ i ) {
14 token = arguments [ i ] ;
15
16 if ( tokens . indexOf ( token ) === - 1 ) {
17 tokens . push ( token ) ;
18 }
19 }
20
21 return startTag [ 1 ] + startTag [ 3 ] + tokens . join ( ' ' ) + startTag [ 5 ] ;
22 }
23
24 var tokens = [ ] ;
25
26 for ( var i = 1 , l = arguments . length ; i < l ; ++ i ) {
27 tokens . push ( arguments [ i ] ) ;
28 }
29
30 return startTag [ 1 ] + ' class="' + tokens . join ( ' ' ) + '"' + startTag [ 2 ] ;
31 }
32
33 function replaceSample ( string ) {
34 var before ;
35
36 return string . replace ( / (<p(?: [^>]*)?>)([^<>]*<\x2Fp>)([^<>]*)|(<[^>]*>)|([^<>]+) / g , function ( match , p1 , p2 , p3 , p4 , p5 ) {
37 if ( p1 ) {
38 var tokens = [ p1 ] , after , length ;
39
40 if ( before ) {
41 tokens . push ( 'before-' + before ) ;
42 }
43
44 after = p3 . match ( / / g ) ;
45
46 if ( after ) {
47 tokens . push ( 'after-' + after . length ) ;
48 before = after . length ;
49 }
50
51 return addClassByStartTag . apply ( null , tokens ) + p2 + p3 ;
52 }
53
54 if ( p4 ) {
55 before = 0 ;
56 }
57
58 if ( p5 ) {
59 before = p5 . match ( / / g ) ;
60 before = before ? before . length : 0 ;
61 }
62
63 return match ;
64 } ) ;
65 }
66
67 function handleSubmit ( event ) {
68 var elements = event . target . elements ;
69
70 event . preventDefault ( ) ;
71 elements [ 'output' ] . value = replaceSample ( elements [ 'input' ] . value ) ;
72 }
73 < / script >
74
75 < Form onsubmit = "handleSubmit(event);" >
76 < p >
77 < textarea name = "input" > & lt ; ! -- HTML の形をしていますが実際にはテキスト ( 文字列 ) です -- & gt ;
78 & lt ; ! -- beforeはdiv直下のみで後は全てafter -- & gt ;
79 & lt ; div & gt ;
80 & amp ; nbsp ;
81 & lt ; p & gt ; 段落 & lt ; / p & gt ;
82 & amp ; nbsp ;
83 & amp ; nbsp ;
84 & amp ; nbsp ;
85 & amp ; nbsp ;
86 & amp ; nbsp ;
87 & amp ; nbsp ;
88 & lt ; p & gt ; 段落 & lt ; / p & gt ;
89 & amp ; nbsp ;
90 & amp ; nbsp ;
91 & lt ; / div & gt ;
92
93 & lt ; div & gt ;
94 & amp ; nbsp ;
95 & amp ; nbsp ;
96 & lt ; p & gt ; 段落 & lt ; / p & gt ;
97 & amp ; nbsp ;
98 & amp ; nbsp ;
99 & amp ; nbsp ;
100 & amp ; nbsp ;
101 & lt ; p & gt ; 段落 & lt ; / p & gt ;
102 & amp ; nbsp ;
103 & lt ; / div & gt ;
104
105 & lt ; div & gt ;
106 & lt ; p & gt ; 段落 & lt ; / p & gt ;
107 & amp ; nbsp ;
108 & lt ; p & gt ; 段落 & lt ; / p & gt ;
109 & amp ; nbsp ;
110 & amp ; nbsp ;
111 & amp ; nbsp ;
112 & lt ; / div & gt ;
113
114 & lt ; ! -- div要素をネストする -- & gt ;
115 & lt ; div & gt ;
116 & lt ; div & gt ;
117 & lt ; ! -- class 属性のあるp要素 -- & gt ;
118 & lt ; p class = "hoge" & gt ; 段落 & lt ; / p & gt ;
119 & amp ; nbsp ;
120 & lt ; p & gt ; 段落 & lt ; / p & gt ;
121 & amp ; nbsp ;
122 & amp ; nbsp ;
123 & amp ; nbsp ;
124 & lt ; / div & gt ; & lt ; / div & gt ; & lt ; div & gt ; & lt ; ! -- テキストノードを挟まない場合 -- & gt ; & lt ; p & gt ; 段落 & lt ; / p & gt ;
125 & amp ; nbsp ;
126 & lt ; p & gt ; 段落 & lt ; / p & gt ;
127 & amp ; nbsp ;
128 & amp ; nbsp ;
129 & amp ; nbsp ;
130 & lt ; / div & gt ;
131 < / textarea >
132 < / p >
133 < p > < input type = "submit" value = "変換" > < / p >
134 < p >
135 < textarea name = "output" > < / textarea >
136 < / p >
137 < / Form >
更新履歴
2016/06/12 06:36 連続するp要素の2つ目以降のp要素の before-n が期待通りに動作しなかった不具合を修正。before-n における
の合計算出時に要素を乗り越えて記録していた不具合を修正(今までのサンプルではホワイトスペースノードで数値がクリアされていたので表面化されていませんでした)。
Re: flat さん
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/06/11 08:05
2016/06/11 09:53
2016/06/11 12:03