首頁 web前端 js教程 JS正規表示式精通實例講解

JS正規表示式精通實例講解

Aug 29, 2019 am 10:55 AM
正規表示式

正则表达式可以: 
1、测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证 
2、替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字 
3、根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字 

正则表达式语法 
一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

创建正则表达式

var re = new RegExp();//RegExp是一个对象,和Aarray一样 
//但这样没有任何效果,需要将正则表达式的内容作为字符串传递进去  
re =new RegExp("a");//最简单的正则表达式,将匹配字母a  
re=new RegExp("a","i");//第二个参数,表示匹配时不分大小写
登入後複製

RegExp构造函数第一个参数为正则表达式的文本内容,而第二个参数则为可选项标志.标志可以组合使用

•g (全文查找)
•i (忽略大小写)
•m (多行查找)

var re = new RegExp("a","gi");//匹配所有的a或A
登入後複製

正则表达式还有另一种正则表达式字面量的声明方式

var re = /a/gi;
登入後複製

正则表达式对象的方法

•test,返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式。如果存在则返回 true,否则就返回 false。
•exec,用正则表达式模式在字符串中运行查找,并返回包含该查找结果的一个数组。
•compile,把正则表达式编译为内部格式,从而执行得更快。
正则表达式对象的属性

//test方法,测试字符串,符合模式时返回true,否则返回false
var re = /he/;//最简单的正则表达式,将匹配he这个单词  
var str = "he";  alert(re.test(str));//true  
str = "we";  alert(re.test(str));//false  
str = "HE";  alert(re.test(str));//false,大写,如果要大小写都匹配可以指定i标志(i是ignoreCase或case-insensitive的表示)  
re = /he/i;  alert(re.test(str));//true  
str = "Certainly!He loves her!";  alert(re.test(str));//true,只要包含he(HE)就符合,如果要只是he或HE,不能有其它字符,
则可使用^和$  
re = /^he/i;//脱字符(^)代表字符开始位置  alert(re.test(str));//false,因为he不在str最开始  
str = "He is a good boy!";  
alert(re.test(str));//true,He是字符开始位置,还需要使用$  
re = /^he$/i;//$表示字符结束位置  
alert(re.test(str));//false  
str = "He";  
alert(re.test(str));//true  //当然,这样不能发现正则表达式有多强大,因为我们完全可以在上面的例子中使用==或indexOf  
re = /\s/;// \s匹配任何空白字符,包括空格、制表符、换页符等等  
str= "user Name";//用户名包含空格  
alert(re.test(str));//true  
str = "user     Name";//用户名包含制表符  
alert(re.test(str));//true  
re=/^[a-z]/i;//[]匹配指定范围内的任意字符,这里将匹配英文字母,不区分大小写  
str="variableName";//变量名必须以字母开头  
alert(re.test(str));//true  
str="123abc";  
alert(re.test(str));//false
登入後複製

当然,仅仅知道了字符串是否匹配模式还不够,我们还需要知道哪些字符匹配了模式

var osVersion = "Ubuntu 8";//其中的8表示系统主版本号  
var re = /^[a-z]+\s+\d+$/i; //+号表示字符至少要出现1次,\s表示空白字符,\d表示一个数字  
alert(re.test(osVersion));//true,但我们想知道主版本号  //另一个方法exec,返回一个数组,数组的第一个元素为完整的匹配内容  
re=/^[a-z]+\s+\d+$/i;  
arr = re.exec(osVersion);  
alert(arr[0]);//将osVersion完整输出,因为整个字符串刚好匹配re  //我只需要取出数字  
re=/\d+/;  
var arr = re.exec(osVersion);  
alert(arr[0]);//8
登入後複製

更复杂的用法,使用子匹配

//exec返回的数组第1到n元素中包含的是匹配中出现的任意一个子匹配  
re=/^[a-z]+\s+(\d+)$/i;//用()来创建子匹配  
arr =re.exec(osVersion);  
alert(arr[0]);//整个osVersion,也就是正则表达式的完整匹配  
alert(arr[1]);//8,第一个子匹配,事实也可以这样取出主版本号  a
lert(arr.length);//2  
osVersion = "Ubuntu 8.10";//取出主版本号和次版本号  
re = /^[a-z]+\s+(\d+)\.(\d+)$/i;//.是正则表达式元字符之一,若要用它的字面意义须转义  
arr = re.exec(osVersion);  
alert(arr[0]);//完整的osVersion  
alert(arr[1]);//8  
alert(arr[2]);//10
登入後複製

注意,当字符串不匹配re时,exec方法将返回null

String对象的一些和正则表达式有关的方法

//replace方法,用于替换字符串  
var str ="some money";  
alert(str.replace("some","much"));//much money  
//replace的第一个参数可以为正则表达式  
var re = /\s/;//空白字符  
alert(str.replace(re,"%"));//some%money  
//在不知道字符串中有多少空白字符时,正则表达式极为方便  
str ="some some             \tsome\t\f";  
re = /\s+/;  
alert(str.replace(re,"#"));//但这样只会将第一次出现的一堆空白字符替换掉  
//因为一个正则表达式只能进行一次匹配,\s+匹配了第一个空格后就退出了  
re = /\s+/g;//g,全局标志,将使正则表达式匹配整个字符串  
alert(str.replace(re,"@"));//some@some@some@ 
//另一个与之相似的是split  
var str = "a-bd-c";  
var arr = str.split("-");//返回["a","bd","c"]  
//如果str是用户输入的,他可能输入a-bd-c也可能输入a bd c或a_bd_c,但不会是abdc(这样就说他输错了)  
str = "a_db-c";//用户以他喜欢的方式加分隔符s  
re=/[^a-z]/i;//前面我们说^表示字符开始,但在[]里它表示一个负字符集  
//匹配任何不在指定范围内的任意字符,这里将匹配除字母处的所有字符  
arr = str.split(re);//仍返回["a","bd","c"];  
//在字符串中查找时我们常用indexOf,与之对应用于正则查找的方法是search  
str = "My age is 18.Golden age!";//年龄不是一定的,我们用indexOf不能查找它的位置  
re = /\d+/;  
alert(str.search(re));//返回查找到的字符串开始下标10  
//注意,因为查找本身就是出现第一次就立即返回,所以无需在search时使用g标志  
//下面的代码虽然不出错,但g标志是多余的  
re=/\d+/g;  alert(str.search(re));//仍然是10
登入後複製

注意,当search方法没有找到匹配时,将返回-1

类似于exec方法,String对象的match方法也用于将字符串与正则表达式进行匹配并返回结果数组

var str = "My name is CJ.Hello everyone!";  
var re = /[A-Z]/;//匹配所有大写字母  
var arr = str.match(re);//返回数组  
alert(arr);//数组中只会包含一个M,因为我们没有使用全局匹配  
re = /[A-Z]/g;  
arr = str.match(re);  
alert(arr);//M,C,J,H  
//从字符串中抽取单词  
re = /\b[a-z]*\b/gi;//\b表示单词边界  
str = "one two three four";  
alert(str.match(re));//one,two,three,four
登入後複製

RegExp对象实例的一些属性

var re = /[a-z]/i;  
alert(re.source);//将[a-z]字符串输出  
//请注意,直接alert(re)会将正则表达式连同前向斜线与标志输出,这是re.toString方法定义的
登入後複製

每个RegExp对象的实例具有lastIndex属性,它是被查找字符串中下一次成功匹配的开始位置,默认值是-1。 lastIndex 属性被 RegExp 对象的 exec 和 test 方法修改.并且它是可写的.

var re = /[A-Z]/;  
//exec方法执行后,修改了re的lastIndex属性,  
var str = "Hello,World!!!";  
var arr = re.exec(str);  
alert(re.lastIndex);//0,因为没有设置全局标志  
re = /[A-Z]/g;  
arr = re.exec(str);  
alert(re.lastIndex);//1  
arr = re.exec(str);  
alert(re.lastIndex);//7
登入後複製

当匹配失败(后面没有匹配),或lastIndex值大于字符串长度时,再执行exec等方法会将lastIndex设为0(开始位置)

var re = /[A-Z]/;  
var str = "Hello,World!!!";  
re.lastIndex = 120;  
var arr = re.exec(str);  
alert(re.lastIndex);//0
登入後複製

RegExp对象的静态属性

//input 最后用于匹配的字符串(传递给test,exec方法的字符串)  
var re = /[A-Z]/;  
var str = "Hello,World!!!";  
var arr = re.exec(str);  
alert(RegExp.input);//Hello,World!!!  
re.exec("tempstr");  
alert(RegExp.input);//仍然是Hello,World!!!,因为tempstr不匹配  
//lastMatch 最后匹配的字符  
re = /[a-z]/g;  
str = "hi";  
re.test(str);  
alert(RegExp.lastMatch);//h  
re.test(str);  
alert(RegExp["$&"]);//i 
$&是lastMatch的短名字,但由于它不是合法变量名,所以要。。  
//lastParen 最后匹配的分组  
re = /[a-z](\d+)/gi;  
str = "Class1 Class2 Class3";  
re.test(str);  
alert(RegExp.lastParen);//1  
re.test(str);  
alert(RegExp["$+"]);//2  
//leftContext  
返回被查找的字符串中从字符串开始位置到最后匹配之前的位置之间的字符  
//rigthContext 返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符  
re = /[A-Z]/g;  
str = "123ABC456";  
re.test(str);  
alert(RegExp.leftContext);//123  
alert(RegExp.rightContext);//BC456  
re.test(str);  
alert(RegExp["$`"]);//123A  
alert(RegExp["$'"]);//C456
登入後複製

multiline属性返回正则表达式是否使用多行模式,这个属性不针对某个正则表达式实例,而是针对所有正则表达式,并且这个属性可写.(IE与Opera不支持这个属性)

alert(RegExp.multiline);  
//因为IE,Opera不支持这个属性,所以最好还是单独指定  
var re = /\w+/m;  
alert(re.multiline);  
alert(RegExp["$*"]);//RegExp对象的静态属性不会因为给RegExp某个对象实例指定了m标志而改变  
RegExp.multiline = true;//这将打开所有正则表达式实例的多行匹配模式 
alert(RegExp.multiline);
登入後複製

使用元字符注意事项:元字符是正则表达式的一部分,当我们要匹配正则表达式本身时,必须对这些元字符转义.下面是正则表达式用到的所有元字符
( [ { \ ^ $ | ) ? * + .

var str = "?";      
var re = /?/;      
alert(re.test(str));//出错,因为?是元字符,必须转义      
re = /\?/;      
alert(re.test(str));//true
登入後複製

使用RegExp构造函数与使用正则表达式字面量创建正则表达式注意点

var str = "\?";  
alert(str);//只会输出?  
var re = /\?/;//将匹配?  
alert(re.test(str));//true  
re = new RegExp("\?");//出错,因为这相当于re = /\?/  
re = new RegExp("\\?");//正确,将匹配?  
alert(re.test(str));//true
登入後複製

既然双重转义这么不友好,所以还是用正则表达式字面量的声明方式

如何在正则表达式中使用特殊字符?

//ASCII方式用十六进制数来表示特殊字符  
var re = /^\x43\x4A$/;//将匹配CJ  
alert(re.test("CJ"));//true  
//也可使用八进制方式  
re = /^\103\112$/;//将匹配CJ  
alert(re.test("CJ"));//true  
//还可以使用Unicode编码  
re =/^\u0043\u004A$/;//使用 Unicode,必须使用u开头,接着是字符编码的四位16进制表现形式  
alert(re.test("CJ"));
登入後複製

另处,还有一些其它的预定义特殊字符,如下表所示:
字符 描述
\n 换行符
\r 回车符
\t 制表符
\f 换页符(Tab)
\cX 与X对应的控制字符
\b 退格符(BackSpace)
\v 垂直制表符
\0 空字符("")

字符类 ---〉简单类,反向类,范围类,组合类,预定义类

//简单类  
var re = /[abc123]/;//将匹配abc123这6个字符中一个  
//负向类  
re = /[^abc]/;//将匹配除abc之外的一个字符  
//范围类  
re = /[a-b]/;//将匹配小写a-b 26个字母  
re = /[^0-9]/;//将匹配除0-9 10个字符之处的一个字符  
//组合类  
re = /[a-b0-9A-Z_]/;//将匹配字母,数字和下划线
登入後複製

预定义类

代码 等同于 匹配
. IE下[^\n],其它[^\n\r] 匹配除换行符之外的任何一个字符
\d [0-9] 匹配数字
\D [^0-9] 匹配非数字字符
\s [ \n\r\t\f\x0B] 匹配一个空白字符
\S [^ \n\r\t\f\x0B] 匹配一个非空白字符
\w [a-zA-Z0-9_] 匹配字母数字和下划线
\W [^a-zA-Z0-9_] 匹配除字母数字下划线之外的字符

量词(下表量词单个出现时皆是贪婪量词)
代码 描述
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

贪婪量词与惰性量词
•用贪婪量词进行匹配时,它首先会将整会字符串当成一个匹配,如果匹配的话就退出,如果不匹配,就截去最后一个字符进行匹配,如果不匹配,继续将最后一个字符截去进行匹配,直到有匹配为止。直到现在我们遇到的量词都是贪婪量词
•用惰性量词进行匹配时,它首先将第一个字符当成一个匹配,如果成功则退出,如果失败,则测试前两个字符,依些增加,直到遇到合适的匹配为止
惰性量词仅仅在贪婪量词后面加个"?"而已,如"a+"是贪婪匹配的,"a+?"则是惰性的

var str = "abc";  
var re = /\w+/;//将匹配abc  
re = /\w+?/;//将匹配a
登入後複製

多行模式

var re = /[a-z]$/;      
var str = "ab\ncdef";      a
lert(str.replace(re,"#"));//ab\ncde#      
re =/[a-z]$/m;      
alert(str.replace(re,"#"));//a#\ncde#
登入後複製

分组与非捕获性分组

re = /abc{2}/;//将匹配abcc  
re = /(abc){2}/;//将匹配abcabc  
//上面的分组都是捕获性分组  
str = "abcabc ###";  
arr = re.exec(str);  
alert(arr[1]);//abc  
//非捕获性分组 (?:)  
re = /(?:abc){2}/;  
arr = re.exec(str);  
alert(arr[1]);//undefined
登入後複製

候选(或)

re = /^a|bc$/;//将匹配开始位置的a或结束位置的bc  
str ="add";  
alert(re.test(str));//true  
re = /^(a|bc)$/;//将匹配a或bc  
str ="bc";  
alert(re.test(str));//true
登入後複製

当包含分组的正则表达式进行过test,match,search这些方法之后,每个分组都被放在一个特殊的地方以备将来使用,这些存储是分组中的特殊值,我们称之为反向引用

var re = /(A?(B?(C?)))/;  
/*上面的正则表达式将依次产生三个分组 
(A?(B?(C?))) 最外面的 
(B?(C?)) 
(C?)*/  
str = "ABC";  re.test(str);//反向引用被存储在RegExp对象的静态属性1—1—9中  
alert(RegExp.$1+"\n"+RegExp.$2+"\n"+RegExp.$3);  
//反向引用也可以在正则表达式中使用\1 ,\2...这类的形式使用  
re = /\d+(\D)\d+\1\d+/;  
str = "2008-1-1";  
alert(re.test(str));//true  
str = "2008-4_3";  
alert(re.test(str));//false
登入後複製

使用反向引用可以要求字符串中某几个位置上的字符必须相同.另外,在replace这类方法中可用特殊字符序列来表示反向引用

re = /(\d)\s(\d)/;  
str = "1234 5678";  
alert(str.replace(re,"221"));//在这个里面1表示第一个分组1234,2则表示5678
登入後複製

其它——〉正向前瞻,用来捕获出现在特定字符之前的字符,只有当字符后面跟着某个特定字符才去捕获它。与正向前瞻对应的有负向前瞻,它用匹配只有当字符后面不跟着某个特定字符时才去匹配它。在执行前瞻和负向前瞻之类的运算时,正则表达式引擎会留意字符串后面的部分,然而却不移动index

//正向前瞻  
re = /([a-z]+(?=\d))/i;  
//我们要匹配后面跟一个数字的单词,然后将单词返回,而不要返回数字  
str = "abc every1 abc"; 
alert(re.test(str));//true  
alert(RegExp.$1);//every  
alert(re.lastIndex);//使用前瞻的好处是,前瞻的内容(?=\d)并不会当成一次匹配,下次匹配仍从它开始  
//负向前瞻(?!)  
re = /([a-z](?!\d))/;i  //将匹配后面不包含数字的字母,并且不会返回(?!\d)中的内容  
str = "abc1 one";  
alert(re.test(str));  
alert(RegExp.$1);//one
登入後複製

构建一个验证电子邮箱地址有效性的正则表达式。电子邮箱地址有效性要求(我们姑且这样定义):用户名只能包含字母数字以及下划线,最少一位,最多25位,用户名后面紧跟@,后面是域名,域名名称要求只能包含字母数字和减号(-),并且不能以减号开头或结尾,然后后面是域名后缀(可以有多个),域名后缀必须是点号连上2-4位英文字母

var re = /^\w{1,15}(?:@(?!-))(?:(?:[a-z0-9-]*)(?:[a-z0-9](?!-))(?:\.(?!-)))+[a-z]{2,4}$/;
登入後複製

更多相关问题请访问PHP中文网:PHP视频教程

以上是JS正規表示式精通實例講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP正規表示式驗證:數位格式偵測 PHP正規表示式驗證:數位格式偵測 Mar 21, 2024 am 09:45 AM

PHP正規表示式驗證:數位格式偵測在編寫PHP程式時,經常需要對使用者輸入的資料進行驗證,其中一個常見的驗證是檢查資料是否符合指定的數字格式。在PHP中,可以使用正規表示式來實現這種驗證。本文將介紹如何使用PHP正規表示式來驗證數字格式,並提供具體的程式碼範例。首先,讓我們來看看常見的數字格式驗證要求:整數:只包含數字0-9,可以以正負號開頭,不包含小數點。浮點

如何使用正規表示式在 Golang 中驗證電子郵件地址? 如何使用正規表示式在 Golang 中驗證電子郵件地址? May 31, 2024 pm 01:04 PM

若要使用正規表示式在Golang中驗證電子郵件地址,請執行下列步驟:使用regexp.MustCompile建立正規表示式模式,以符合有效的電子郵件地址格式。使用MatchString函數檢查字串是否與模式相符。此模式涵蓋了大多數有效的電子郵件地址格式,包括:局部使用者名稱可以包含字母、數字和特殊字元:!.#$%&'*+/=?^_{|}~-`網域至少包含一個字母,後面可以跟字母、數字或連字符頂級域名(TLD)不能超過63個字符長

如何在 Go 中使用正規表示式匹配時間戳記? 如何在 Go 中使用正規表示式匹配時間戳記? Jun 02, 2024 am 09:00 AM

在Go中,可以使用正規表示式比對時間戳記:編譯正規表示式字串,例如用於匹配ISO8601時間戳記的表達式:^\d{4}-\d{2}-\d{2}T \d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-][0-9]{2}:[0-9]{2})$ 。使用regexp.MatchString函數檢查字串是否與正規表示式相符。

掌握Go語言的正規表示式和字串處理 掌握Go語言的正規表示式和字串處理 Nov 30, 2023 am 09:54 AM

Go語言作為一門現代化的程式語言,提供了強大的正規表示式和字串處理功能,使得開發者能夠更有效率地處理字串資料。掌握Go語言的正規表示式和字串處理,對於開發者來說是非常重要的。本文將詳細介紹Go語言中正規表示式的基本概念和用法,以及如何使用Go語言處理字串。一、正規表示式正規表示式是用來描述字串模式的工具,能夠方便地實現字串的匹配、尋找和替換等操

PHP正規表示式:精確匹配與排除模糊包含 PHP正規表示式:精確匹配與排除模糊包含 Feb 28, 2024 pm 01:03 PM

PHP正規表示式:精確匹配與排除模糊包含正規表示式是一種強大的文字匹配工具,能夠幫助程式設計師在處理文字時進行高效的搜尋、替換和篩選。在PHP中,正規表示式也被廣泛應用於字串處理和資料匹配。本文將重點介紹在PHP中如何進行精確配對和排除模糊包含的操作,同時結合具體的程式碼範例進行說明。精確匹配精確匹配意味著只匹配符合完全條件的字串,不匹配任何變種或包含額外字

如何在 Go 中使用正規表示式驗證密碼? 如何在 Go 中使用正規表示式驗證密碼? Jun 02, 2024 pm 07:31 PM

Go中使用正規表示式驗證密碼的方法如下:定義正規表示式模式,符合最低密碼要求:至少8個字符,包含小寫字母、大寫字母、數字和特殊字符。使用regexp套件中的MustCompile函式編譯正規表示式模式。使用MatchString方法測試輸入字串是否與正規表示式模式相符。

中文字元過濾:PHP正規表示式實踐 中文字元過濾:PHP正規表示式實踐 Mar 24, 2024 pm 04:48 PM

PHP是一種廣泛應用的程式語言,特別在Web開發領域中非常流行。在網路開發過程中,經常會遇到需要對使用者輸入的文字進行過濾、驗證等操作,其中字元過濾是一項十分重要的操作。本文將介紹如何使用PHP中的正規表示式來實現中文字元過濾的功能,並給出具體的程式碼範例。首先,我們要先明確一下中文字元的Unicode範圍是從u4e00到u9fa5,也就是所有的漢字都處於這個範圍

正規表示式通配符有哪些 正規表示式通配符有哪些 Nov 17, 2023 pm 01:40 PM

正規表示式通配符有"."、"*"、"+"、"?"、"^"、"$"、"[]"、"[^]"、"[a-z]"、"[A-Z] "、"[0-9]"、"\d"、"\D"、"\w"、"\W"、"\s&quo

See all articles