众所周知,在程序开发中,难免会遇到需要匹配、查找、替换、判断字符串的情况发生,而这些情况有时又比较复杂,如果用纯编码方式解决,往往会浪费程序员的时间及精力。因此,学习及使用正则表达式,便成了解决这一矛盾的主要手段。
 大 家都知道,正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
  自从jdk1.4推出java.util.regex包,就为我们提供了很好的JAVA正则表达式应用平台。
 
 因为正则表达式是一个很庞杂的体系,所以我仅例举些入门的概念,更多的请参阅相关书籍及自行摸索。

// 反斜杠
/t 间隔 ('/u0009')
/n 换行 ('/u000A')
/r 回车 ('/u000D')
/d 数字 等价于[0-9]
/D 非数字 等价于[^0-9]
/s 空白符号 [/t/n/x0B/f/r]
/S 非空白符号 [^/t/n/x0B/f/r]
/w 单独字符 [a-zA-Z_0-9]
/W 非单独字符 [^a-zA-Z_0-9]
/f 换页符
/e Escape
/b 一个单词的边界
/B 一个非单词的边界
/G 前一个匹配的结束

^为限制开头
^java     条件限制为以Java为开头字符
$为限制结尾
java$     条件限制为以java为结尾字符
.  条件限制除/n以外任意一个单独字符
java..     条件限制为java后除换行外任意两个字符

加入特定限制条件「[]」
[a-z]     条件限制在小写a to z范围中一个字符
[A-Z]     条件限制在大写A to Z范围中一个字符
[a-zA-Z] 条件限制在小写a to z或大写A to Z范围中一个字符
[0-9]     条件限制在小写0 to 9范围中一个字符
[0-9a-z] 条件限制在小写0 to 9或a to z范围中一个字符
[0-9[a-z]] 条件限制在小写0 to 9或a to z范围中一个字符(交集)

[]中加入^后加再次限制条件「[^]」
[^a-z]     条件限制在非小写a to z范围中一个字符
[^A-Z]     条件限制在非大写A to Z范围中一个字符
[^a-zA-Z] 条件限制在非小写a to z或大写A to Z范围中一个字符
[^0-9]     条件限制在非小写0 to 9范围中一个字符
[^0-9a-z] 条件限制在非小写0 to 9或a to z范围中一个字符
[^0-9[a-z]] 条件限制在非小写0 to 9或a to z范围中一个字符(交集)

在限制条件为特定字符出现0次以上时,可以使用「*」
J*     0个以上J
.*     0个以上任意字符
J.*D     J与D之间0个以上任意字符

在限制条件为特定字符出现1次以上时,可以使用「+」
J+     1个以上J
.+     1个以上任意字符
J.+D     J与D之间1个以上任意字符

在限制条件为特定字符出现有0或1次以上时,可以使用「?」
JA?     J或者JA出现

限制为连续出现指定次数字符「{a}」
J{2}     JJ
J{3}     JJJ
文字a个以上,并且「{a,}」
J{3,}     JJJ,JJJJ,JJJJJ,???(3次以上J并存)
文字个以上,b个以下「{a,b}」
J{3,5}     JJJ或JJJJ或JJJJJ
两者取一「|」
J|A     J或A
Java|Hello     Java或Hello
 
「()」中规定一个组合类型
比如,我查询<a href=/"index.html/">index</a>中<a href></a>间的数据,可写作<a.*href=/".*/">(.+?)</a>

在使用Pattern.compile函数时,可以加入控制正则表达式的匹配行为的参数:
Pattern Pattern.compile(String regex, int flag)

 
Java代码 
  1. public class RegexHarnessTest
  2. {
  3. public static void main(String args[])
  4. {
  5. String[] regex = {"([\u4E00-\u9FA5]+,?)+",
  6. "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}",
  7. "\\d{4}[A-Z]{2}",
  8. "[0-9]{1.3}"};
  9. String[] input = {"开发高手,程序员的朋友,开发者的助手",
  10. "IP:71.42.164.8,192.168.1.1,7.78.3.221",
  11. "美国汽车牌照:3456MW,12345M,6789NY",
  12. "数字:345,678"};
  13. RegexHarness rh = new RegexHarness();
  14. for(int i=0;i<regex.length;i++)
  15. {
  16. rh.setRegex(regex[i]);
  17. rh.setInput(input[i]);
  18. if(rh.initialize())
  19. {
  20. System.out.println("\n-----匹配方式:全文匹配,方法:matches调用开始-----\n");
  21. rh.validateEntireText();
  22. System.out.println(rh.getResults());
  23. System.out.println("\n-----匹配方式:全文匹配,方法:matches调用结束-----\n");
  24. System.out.println("\n-----匹配方式:部分匹配,方法:find调用开始-----\n");
  25. rh.validatePartText();
  26. System.out.println(rh.getResults());
  27. System.out.println("\n-----匹配方式:部分匹配,方法:find调用结束-----\n");
  28. }
  29. else
  30. {
  31. System.out.println(rh.getRegexError());
  32. }
  33. }
  34. System.exit(0);
  35. }
  36. }
Java代码 
  1. import java.util.regex.Matcher;
  2. import java.util.regex.Pattern;
  3. import java.util.regex.PatternSyntaxException;
  4. public class RegexHarness
  5. {
  6. /**regex表示正则表达式,input表示要匹配或验证的文本或字符串*/
  7. private String regex="",input="";
  8. /**regexError表示当正则表达式出现语法错误时,相关的错误信息
  9. * results表示匹配后的结果*/
  10. private String regexError="",results="";
  11. private Pattern pattern;
  12. private Matcher matcher;
  13. public RegexHarness()
  14. {
  15. this("","");
  16. }
  17. public RegexHarness(String regex,String input)
  18. {
  19. setRegex(regex);
  20. setInput(input);
  21. }
  22. /**
  23. * 初始化
  24. * @return
  25. */
  26. public boolean initialize()
  27. {
  28. try
  29. {
  30. /*
  31. * 使用Pattern类的静态compile方法,接收一个代表正则
  32. * 表达式的字符串(变量:regex)的参数,并返回一个指定的
  33. * 正则表达式的Pattern对象的pattern
  34. */
  35. pattern = Pattern.compile(regex);
  36. /*
  37. * 利用刚刚返回的Pattern类的实例pattern,并调用pattern
  38. * 的matcher方法。该方法接收一个用于匹配的实现了CharSequence
  39. * 接口的对象input,并将返回一个Matcher对象赋值给变量matcher。
  40. */
  41. matcher = pattern.matcher(input);
  42. return true;
  43. }
  44. catch (PatternSyntaxException pse) {
  45. regexError = "\n正则表达式语法错误!错误的相关信息如下:" +
  46. "\n当前的正则表达式是:" + pse.getPattern() +
  47. "\n错误描述:" + pse.getDescription() +
  48. "\n错误信息:" + pse.getMessage() +
  49. "\n错误索引:" + pse.getIndex();
  50. return false;
  51. }
  52. }
  53. /**
  54. * 根据正则表达式来匹配输入的整个文本,并得到匹配结果<br>
  55. * 本方法不返回任何数据,先调用matcher的方法matches,
  56. * matches方法根据给定的正则表达式来匹配的整个文本。
  57. * 如果整个文本都匹配给定的正则表达式,就调用matcher的
  58. * group方法,该方法返回与查找模式相匹配的查找对象的字符
  59. * 串,并将得到的匹配文本再赋值给字符串变量results,返回
  60. * 真值。
  61. */
  62. public void validateEntireText()
  63. {
  64. boolean findMathText = false;
  65. results = "当前的正则表达式是:" + regex +
  66. "\n当前匹配的文本是:" + input + "\n\n";
  67. if(matcher.matches())
  68. {
  69. results += "找到全文匹配的文本\"" + matcher.group() + "\"。\n";
  70. findMathText = true;
  71. }
  72. if(!findMathText)
  73. {
  74. results += "没有发现全文匹配的文本。\n";
  75. }
  76. }
  77. /**
  78. * 根据正则表达式来匹配输入的部分文本,并得到匹配结果<br>
  79. * 本方法不返回任何数据,但是调用的是matcher的方法find,
  80. * find方法根据给定的正则表达式来匹配的文本中的子字符串。
  81. * 和matches方法不同之处在于,只有被匹配的文本中的部分内容
  82. * 符合给定的正则表达式时,find方法才返回真值。
  83. */
  84. public void validatePartText()
  85. {
  86. boolean findMathText = false;
  87. results = "当前的正则表达式是:" + regex +
  88. "\n当前匹配的文本是:" + input + "\n\n";
  89. while(matcher.find())
  90. {
  91. results += "找到部分匹配的文本\"" + matcher.group()+
  92. "\"\t起始索引:" + matcher.start() +
  93. "\t结束索引:" + matcher.end() + "。\n";
  94. findMathText = true;
  95. }
  96. if(!findMathText)
  97. {
  98. results += "没有发现部分匹配的文本。\n";
  99. }
  100. }
  101. public String getResults()
  102. {
  103. return this.results;
  104. }
  105. public String getRegexError()
  106. {
  107. return this.regexError;
  108. }
  109. public void setRegex(String regex)
  110. {
  111. this.regex = regex;
  112. }
  113. public void setInput(String input)
  114. {
  115. this.input = input;
  116. }
  117. }
Java代码 
  1. import javax.swing.JOptionPane;
  2. public class RegexStringReplace
  3. {
  4. public static void main(String args[])
  5. {
  6. String originalString = "This is 哈哈 JAVA code* * * * *";
  7. String output = "原始字符串:"+ originalString;
  8. //替换'*' 为 '^'
  9. originalString = originalString.replaceAll("\\*", "^ ");
  10. output+="\n*被替换成^ 后的字符串:"+originalString;
  11. //替换'哈哈'为'HaHa's'
  12. originalString = originalString.replaceAll("哈哈", "HaHa's");
  13. output+="\n\"哈哈\"替换成\"HaHa's\":"+originalString;
  14. //将字符串中的每个单词都替换成"word"
  15. output+="\n每个单词都替换成\"word\":"+originalString.replaceAll("\\w+", "word");
  16. JOptionPane.showMessageDialog(null, output,"Java正则表达式例子",JOptionPane.INFORMATION_MESSAGE);
  17. System.exit(0);
  18. }
  19. }
Java代码 
  1. import javax.swing.JOptionPane;
  2. public class RegexStringReplaceFirstAndSplit
  3. {
  4. public static void main(String args[])
  5. {
  6. String originalString="1, one, 2, two, 3, three, 4, four, 5, five";
  7. String output = "原始字符串:\n" + originalString;
  8. //迭代3次,将字符串中第一次出现的数字替换成字符串'dight'
  9. for(int i=0;i<3;i++)
  10. {
  11. originalString = originalString.replaceFirst("\\d", "digit");
  12. }
  13. output += "\n头三个数字被替换成\"digit\"后的字符串:\n" + originalString;
  14. //分隔出现逗号的子字符串,逗号后面可以匹配任意的空白字符
  15. String[] result = originalString.split(",\\s*");
  16. output +="\n字符串依据逗号来分割后的结果";
  17. for(int i=0;i<result.length;i++)
  18. {
  19. output+="\n"+result[i];
  20. }
  21. JOptionPane.showMessageDialog(null, output,"java正则表达式",JOptionPane.INFORMATION_MESSAGE);
  22. System.exit(0);
  23. }
  24. }
Java代码 
  1. import java.awt.Container;
  2. import java.awt.Font;
  3. import java.awt.GridLayout;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import javax.swing.JButton;
  7. import javax.swing.JFrame;
  8. import javax.swing.JLabel;
  9. import javax.swing.JOptionPane;
  10. import javax.swing.JPanel;
  11. import javax.swing.JTextField;
  12. public class RegexStringTest extends JFrame
  13. {
  14. private static final long serialVersionUID = -1564020173888781534L;
  15. private JTextField phoneTextField;
  16. private JTextField zipTextField;
  17. private JTextField addressTextField;
  18. private JTextField firstTextField;
  19. private JTextField lastTextField;
  20. private JTextField chineseTextField;
  21. private Font songTi = new Font("宋体",Font.PLAIN,12);
  22. public RegexStringTest()
  23. {
  24. super("基于字符串的正则表达式");
  25. //创建图形界面
  26. JLabel phoneLabel = new JLabel("电话");
  27. phoneLabel.setFont(songTi);
  28. JLabel zipLabel = new JLabel("邮政编码");
  29. zipLabel.setFont(songTi);
  30. JLabel addressLabel = new JLabel("通信地址");
  31. addressLabel.setFont(songTi);
  32. JLabel firstLabel = new JLabel("First Name:(英文,第一个字母必须大写)");
  33. firstLabel.setFont(songTi);
  34. JLabel lastLabel = new JLabel("Last Name:(英文,第一个字母必须大写)");
  35. lastLabel.setFont(songTi);
  36. JLabel chineseLabel = new JLabel("中文");
  37. chineseLabel.setFont(songTi);
  38. JButton okButton =  new JButton("验证");
  39. okButton.setFont(songTi);
  40. okButton.addActionListener(new ActionListener()
  41. {
  42. //内部类开始
  43. public void actionPerformed(ActionEvent e) {
  44. validateDate();
  45. }//内部类结束
  46. });//调用addActionListener结束
  47. phoneTextField = new JTextField(15);
  48. zipTextField = new JTextField(6);
  49. addressTextField = new JTextField(35);
  50. firstTextField = new JTextField(20);
  51. lastTextField = new JTextField(20);
  52. chineseTextField = new JTextField(30);
  53. JPanel firstName = new JPanel();
  54. firstName.add(firstLabel);
  55. firstName.add(firstTextField);
  56. JPanel lastName = new JPanel();
  57. lastName.add(lastLabel);
  58. lastName.add(lastTextField);
  59. JPanel address = new JPanel();
  60. address.add(addressLabel);
  61. address.add(addressTextField);
  62. JPanel zipAndPhone = new JPanel();
  63. zipAndPhone.add(zipLabel);
  64. zipAndPhone.add(zipTextField);
  65. zipAndPhone.add(phoneLabel);
  66. zipAndPhone.add(phoneTextField);
  67. JPanel chinese = new JPanel();
  68. chinese.add(chineseLabel);
  69. chinese.add(chineseTextField);
  70. JPanel ok = new JPanel();
  71. ok.add(okButton);
  72. //把GUI部件添加在容器中
  73. Container container = getContentPane();
  74. container.setLayout(new GridLayout(6,1));
  75. container.add(firstName);
  76. container.add(lastName);
  77. container.add(address);
  78. container.add(zipAndPhone);
  79. container.add(chinese);
  80. container.add(ok);
  81. pack();
  82. setVisible(true);
  83. }//RegexStringTest构造器结束
  84. public static void main(String args[])
  85. {
  86. RegexStringTest application = new RegexStringTest();
  87. application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  88. }
  89. /**
  90. * 处理鼠标点击事件
  91. */
  92. private void validateDate()
  93. {
  94. //确保每个文本框不为空
  95. if(lastTextField.getText().equals("") ||
  96. firstTextField.getText().equals("")||
  97. addressTextField.getText().equals("")||
  98. zipTextField.getText().equals("")||
  99. phoneTextField.getText().equals("")||
  100. chineseTextField.getText().equals(""))
  101. {
  102. JOptionPane.showMessageDialog(this, "每个栏目都必须填写");
  103. }
  104. else if(!firstTextField.getText().matches("[A-Z][a-zA-Z]*"))
  105. {//验证First Name是不是以大写字母的一个英文单词
  106. /*
  107. * [A-Z]匹配单个大写字母,其后面的[a-zA-Z]*表示可以匹配任意数目的
  108. * 字母。通常,在正则表达式中出现运算符(量词)"*"的时候,程序将匹配
  109. * "*"前的0个或多个子表达式。同理,"A*"和"A+"都与"A"匹配,但"A*"
  110. * 还可以匹配一个空的字符串。
  111. */
  112. JOptionPane.showMessageDialog(this, "First Name非法");
  113. }
  114. else if(!lastTextField.getText().matches("[A-Z][a-zA-Z]*"))
  115. {//验证Last Name是不是以大写字母开头的一个英文单词
  116. JOptionPane.showMessageDialog(this, "Last Name非法");
  117. }
  118. else if(!addressTextField.getText().matches("\\d+\\s+([a-zA-Z]+|[a-zA-Z]+\\s[a-zA-Z]+)"))
  119. {//验证地址是否为数字开始,并包含一个单词或者两个单词
  120. /*
  121. * 这里的地址格式是西方的格式,也就是门牌号在前,街名在后。
  122. * \\d+\\s+([a-zA-Z]+|[a-zA-Z]+\\s[a-zA-Z]+)
  123. * 首先是匹配任意的数字(\\d+),"\d"是表示数字字符,这里之所以要加上一个"\"
  124. * 是因为"\"在Java中是作用转义字符的。所以这里的"\\d"就正好表示正则表达
  125. * 式中的"\d"。然后,继续验证数字后面是否至少有一个空白字符(\\s+)。字符
  126. * "|"将表达式与其左边或者右边的字符串相匹配。如:Hello(Tom|Rich)就和
  127. * Hello Tom以及Hello Rich相匹配。括号用于将正则表达式的各个部分连接
  128. * 起来。这里字符"|"左边([a-zA-Z]+)匹配一个单词,而右边
  129. * ([a-zA-Z]+\\s[a-zA-Z]+)匹配两个单词,注意两个单词之间只能有一个空白
  130. * 字符(\\s)。因此,这里如果用户输入"123 Main"或者"123 Main Street"
  131. * 都是有效的。
  132. */
  133. JOptionPane.showMessageDialog(this, "地址非法");
  134. }
  135. else if(!zipTextField.getText().matches("\\d{5}"))
  136. {//验证邮政编码是否为一个5位数的数字
  137. /*
  138. * "\\d{5}"表明邮政编码匹配5个数字。另外可以用其他写法实现相同的功能
  139. * 如:"[0-9]{5}"
  140. */
  141. JOptionPane.showMessageDialog(this, "邮政编码非法");
  142. }
  143. else if(!phoneTextField.getText().matches("[1-9]\\d{2}-[1-9]\\d{2}-\\d{4}"))
  144. {//验证电话号码格式是否为123-456-7890并且区号和电话号码的第一位不能是数字0
  145. /*
  146. * [1-9]\\d{2}-[1-9]\\d{2}-\\d{4}
  147. * 本例采用的美国的电话号码形式,如123-456-7890,即头三位数字为区号
  148. * ,之后紧跟一个短横线,接着是电话号码的头三位,之后又是一个短横线,
  149. * 最后是电话号码的最后四位数。注意这里"[1-9]\\d{2}"表示匹配一个3位
  150. * 数的数字,但其第一个数字不能为0.如果希望123-4567890这种格式的电话
  151. * 号码也合法,可以修改"[1-9]\\d{2}-[1-9]\\d{2}-?\\d{4}"
  152. * 我们在第2个短横线后加一个"?"号,表示"-"可以出现,也可以不出现。
  153. */
  154. JOptionPane.showMessageDialog(this, "非法的电话号码");
  155. }
  156. else if(!chineseTextField.getText().matches("[\u4E00-\u9FA5]+"))
  157. {
  158. /*
  159. * [\u4E00-\u9FA5]+,验证了用户输入的数据是否全部为中文字符。
  160. */
  161. JOptionPane.showMessageDialog(this, "只能输入中文");
  162. }
  163. else
  164. {
  165. JOptionPane.showMessageDialog(this, "谢谢,您输入的完全合法");
  166. }
  167. }
  168. }

Java正则表达式基础知识及实例说明的更多相关文章

  1. java正则表达式基础知识(转)

    1基础 2.1 简单字符类 构造 描述 [abc] a,b或c [^abc] 除a,b或c外的字符 [a-zA-Z] a至z 或 A至Z [a-d[m-p]] a至d 或 m至p [a-z&& ...

  2. Java正则表达式基础知识整理

    指定为字符串的正则表达式必须首先被编译为此类的实例.然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配.执行匹配所涉及的所有状态都驻留在匹配器中,所以多个 ...

  3. Java 多线程——基础知识

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  4. javascript之正则表达式基础知识小结

    javascript之正则表达式基础知识小结,对于学习正则表达式的朋友是个不错的基础入门资料.   元字符 ^ $ . * + ? = ! : | \ / ( ) [ ] { } 在使用这些符号时需要 ...

  5. JAVA相关基础知识

    JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分, ...

  6. java必备基础知识(一)

    学习的一点建议: 每一门语言的学习都要从基础知识开始,学习是一个过程,"万丈高楼平地起",没有一个好的地基,想必再豪华的高楼大厦终究有一天会倒塌.因此,我们学习知识也要打牢根基,厚 ...

  7. 什么才是java的基础知识?

    近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考. ...

  8. java部分基础知识整理----百度脑图版

    近期发现,通过百度脑图可以很好的归纳总结和整理知识点,本着学习和复习的目的,梳理了一下java部分的知识点,不定期更新,若有不恰之处,请指正,谢谢! 脑图链接如下:java部分基础知识整理----百度 ...

  9. Scala学习笔记--正则表达式基础知识、如何在scala内使用

    正则表达式语法:https://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx 基础知识:正则表达式30分钟入门教程 http://www. ...

随机推荐

  1. Java 借助poi操作PDF工具类

    ​ 一直以来说写一个关于Java操作PDF的工具类,也没有时间去写,今天抽空写一个简单的工具类,拥有PDF中 换行,字体大小,字体设置,字体颜色,首行缩进,居中,居左,居右,增加新一页等功能,如果需要 ...

  2. 如何在win10下使用Ubuntu中的crontab自动执行任务

    win10下如何下载ubuntu 1.打开Microsoft Store,搜索ubuntu,选择其一(我选了第一个),点击获取,耐心等待安装即可:   2.安装完成可在开始栏找到:   使用cront ...

  3. python3爬虫爬取金庸小说所有角色

    # -*- coding:utf-8 -*- import requests from bs4 import BeautifulSoup url = 'http://www.jinyongwang.c ...

  4. ORM常用字段及方式

    创建小型数据库 模型层 ORM常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. Integer ...

  5. Grid Illumination

    2019-07-07 16:53:31 问题描述: 问题求解: 本题和n后问题很类似,所以最初的时候就直接套了n后的板子,MLE. public int[] gridIllumination(int ...

  6. UVa 11059 最大乘积 java 暴力破解

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  7. Tail Call

    一.什么是尾调用 尾调用(Tail Call)是函数式编程的一个重要概念. 一个函数里的最后一个动作是返回一个函数的调用结果,用简单的一句话描述就是"在函数的最后一步调用函数". ...

  8. Centos7 中打开和关闭防火墙及端口

    1.firewalld的基本使用 启动: systemctl start firewalld 关闭: systemctl stop firewalld 查看状态: systemctl status f ...

  9. JS 剑指Offer(三) 替换字符串中的空格

    请实现一个函数,把字符串 s 中的每个空格替换成"%20". 实现这个函数的方法很简单,在JS中可以直接应用正则表达式,代码如下 直接将全局中的space换成%20,一行代码搞定 ...

  10. P1006 传纸条(二维、三维dp)

    P1006 传纸条 输入输出样例 输入 #1 复制 3 3 0 3 9 2 8 5 5 7 0 输出 #1 复制 34 说明/提示 [限制] 对于 30% 的数据,1≤m,n≤10: 对于 100% ...