关于regex:使用正则表达式验证数值范围

Using regular expressions to validate a numeric range

我的输入数字是一个整数,但是输入数字必须在-2055到2055的范围内,我想使用正则表达式来检查这一点。

那么,是否有必要编写一个正则表达式来检查数字是否在(-20552055)中?

使用if语句更容易检查数字是否在范围内。但是我正在编写一个解释器,所以我应该使用regex来检查输入编号


使用正则表达式验证数值范围好的。

要清楚:何时简单的if语句就足够了好的。好的。

1
2
3
if(num < -2055  ||  num > 2055)  {
   throw  new IllegalArgumentException("num (" + num +") must be between -2055 and 2055");
}

不建议使用正则表达式验证数值范围。好的。好的。

此外,由于正则表达式分析字符串,因此必须先将数字转换为字符串,然后才能对其进行测试。一个例外是当数字恰好已经是一个字符串时,例如从控制台获取用户输入时。好的。好的。

(为了确保该字符串是一个开始使用的数字,您可以使用org.apache.apache.commons.lang3.math.a href="http://commons.apache.org/prope/commons-lang/javadocs/api-3.2/org/apache/commons/lang3/math/numbeutils.html"rel="noreferr">numbeutils;/a a ;a href="http://commons.apache.org/prope/commons-lang/commons-lang3.lang3.lang3.math.lang3.math.;a a a a a href="http://commons.apcommons.apache.apache.apache.apache/commons/commons/lang三/Mault/NoMultuuts.html HTML iStIt(Java.Lang.Stand)"Re= = NordeFror"> Is(s){A/AA} < /代码>好的。好的。

尽管如此,找出如何用正则表达式验证数字范围还是很有意思和指导意义的。好的。好的。

(此答案中的链接来自堆栈溢出正则表达式常见问题解答。)好的。

一个数字范围好的。

规则:数字必须正好是15。好的。好的。

最简单的范围。与此匹配的正则表达式是好的。

1
\b15\b

为了避免与8215242内部的15相匹配,必须使用单词边界。好的。

两位数范围好的。

规则:数字必须在1516之间。有三种可能的正则表达式:好的。

1
2
3
\b(15|16)\b
\b1(5|6)\b
\b1[5-6]\b

(这些组是"或"所必需的,但它们可能无法捕获:\b(?:15|16)\b)好的。

数字范围"镜像"在零附近好的。

规则:数字必须在-1212之间。好的。好的。

以下是从012的regex,仅为正数:好的。好的。

1
\b(\d|1[0-2])\b

自由间隔:好的。好的。

1
2
3
4
5
\b(         //The beginning of a word (or number), followed by either
   \d       //   Any digit 0 through 9
|           //Or
   1[0-2]   //   A 1 followed by any digit between 0 and 2.
)\b         //The end of a word

使这对负和正都有效,就如同在开始时添加可选的破折号一样简单:好的。好的。

1
-?\b(\d|1[0-2])\b

(这假定破折号前面没有不适当的字符。)好的。

要禁止负数,必须进行反向查找:好的。

1
(?<!-)\b(\d|1[0-2])\b

离开了望台会使-11中的11匹配。(本文的第一个示例应该添加此内容。)好的。好的。

注:\d[0-9]的比较好的。

为了与所有regex口味兼容,所有\ds应改为[0-9]。例如,.net将非ASCII数字(例如不同语言的数字)视为\d的合法值。除了最后一个例子,为了简洁起见,它被保留为\d。好的。好的。

(感谢a href="https://stackoverflow.com/users/20670/tim pietzcker">@tim pietzcker/a a)好的。好的。

三位数,除第一位数外,其余均等于零好的。

规则:必须在0400之间。好的。好的。

一个可能的正则表达式:好的。好的。

1
(?<!-)\b([1-3]?\d{1,2}|400)\b

自由间隔:好的。好的。

1
2
3
4
5
6
7
   (?<!-)          //Something not preceded by a dash
   \b(             //Word-start, followed by either
      [1-3]?       //   No digit, or the digit 1, 2, or 3
         \d{1,2}   //   Followed by one or two digits (between 0 and 9)
   |               //Or
      400          //   The number 400
   )\b             //Word-end

另一种不应使用的可能性是:好的。好的。

1
\b(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255|256|257|258|259|260|261|262|263|264|265|266|267|268|269|270|271|272|273|274|275|276|277|278|279|280|281|282|283|284|285|286|287|288|289|290|291|292|293|294|295|296|297|298|299|300|301|302|303|304|305|306|307|308|309|310|311|312|313|314|315|316|317|318|319|320|321|322|323|324|325|326|327|328|329|330|331|332|333|334|335|336|337|338|339|340|341|342|343|344|345|346|347|348|349|350|351|352|353|354|355|356|357|358|359|360|361|362|363|364|365|366|367|368|369|370|371|372|373|374|375|376|377|378|379|380|381|382|383|384|385|386|387|388|389|390|391|392|393|394|395|396|397|398|399|400)\b

最后一个例子:四位数字,镜像在零周围,不以零结尾。好的。

规则:必须在-20552055之间好的。好的。

这是来自a a href="https://stackoverflow.com/q/22130429/2736496">stackoverflow上的问题/a a。好的。好的。

Regex:好的。好的。

1
(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2}|(?<!-)0+))\b

Regular expression visualization好的。

调试程序演示好的。

自由间隔:好的。好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(             //Capture group for the entire number
   -?\b             //Optional dash, followed by a word (number) boundary
   (?:20            //Followed by"20", which is followed by one of
         (?:5[0-5]        //50 through 55
           |                  //or
         [0-4][0-9])      //00 through 49
      |                                         //or
         1[0-9]{3}        //a one followed by any three digits
      |                                         //or
         [1-9][0-9]{0,2}  //1-9 followed by 0 through 2 of any digit
      |                                         //or
         (?<!-)0+         //one-or-more zeros *not* preceded by a dash
   )                 //end"or" non-capture group
)\b            //End number capture group, followed by a word-bound

(感谢a href="https://stackoverflow.com/users/3352674/plasmapower">plasmapower/a a和casimir et hippolyte提供调试帮助。)好的。好的。

期末笔记好的。

根据您的身份a href="http://www.regular-expressions.info/brackets.html"rel="noreferrer">捕获/a a,很可能所有子组都应成为非捕获组。例如,这:好的。好的。

1
(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1?[0-9]{1,3})\b)

而不是这个:好的。好的。

1
-?\b(20(5[0-5]|[0-4][0-9])|1?[0-9]{1,3})\b

Java实现实例好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  import  java.util.Scanner;
  import  java.util.regex.Matcher;
  import  java.util.regex.Pattern;
  import  org.apache.commons.lang.math.NumberUtils;
/**
  <p>
Confirm a user-input number is a valid number by reading a string an testing it is numeric before converting it to an it--this loops until a valid number is provided.
</p>Ok.



  <p>
{@code java UserInputNumInRangeWRegex}
</p>Ok.


 **/
public class UserInputNumInRangeWRegex  {
  public static final void main(String[] ignored)  {

     int num = -1;
     boolean isNum = false;

     int iRangeMax = 2055;

     //"": Dummy string, to reuse matcher
     Matcher mtchrNumNegThrPos = Pattern.compile("(-?\\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2}|(?<!-)0+))\\b").matcher("");

     do  {
        System.out.print("Enter a number between -" + iRangeMax +" and" + iRangeMax +":");
        String strInput = (new Scanner(System.in)).next();
        if(!NumberUtils.isNumber(strInput))  {
           System.out.println("Not a number. Try again.");
        }  else if(!mtchrNumNegThrPos.reset(strInput).matches())  {
           System.out.println("Not in range. Try again.");
        }  else  {
           //Safe to convert
           num = Integer.parseInt(strInput);
           isNum = true;
        }
     }  while(!isNum);

     System.out.println("Number:" + num);
  }

}好的。

产量好的。好的。

1
2
3
4
5
6
7
8
9
[C:\java_code\]java UserInputNumInRangeWRegex
Enter a number between -2055 and 2055: tuhet
Not a number. Try again.
Enter a number between -2055 and 2055: 283837483
Not in range. Try again.
Enter a number between -2055 and 2055: -200000
Not in range. Try again.
Enter a number between -2055 and 2055: -300
Number: -300

此StackOverflow问题的原始答案好的。

这是一个符合您规格的严肃回答。这类似于@plasmapower的答案。好的。

1
(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2}|(?<!-)0+))\b

Regular expression visualization好的。

调试程序演示好的。好啊。


别用它,但这很管用。:)

1
\b(-2055|-2054|-2053|-2052|-2051|-2050|-2049|-2048|-2047|-2046|-2045|-2044|-2043|-2042|-2041|-2040|-2039|-2038|-2037|-2036|-2035|-2034|-2033|-2032|-2031|-2030|-2029|-2028|-2027|-2026|-2025|-2024|-2023|-2022|-2021|-2020|-2019|-2018|-2017|-2016|-2015|-2014|-2013|-2012|-2011|-2010|-2009|-2008|-2007|-2006|-2005|-2004|-2003|-2002|-2001|-2000|-1999|-1998|-1997|-1996|-1995|-1994|-1993|-1992|-1991|-1990|-1989|-1988|-1987|-1986|-1985|-1984|-1983|-1982|-1981|-1980|-1979|-1978|-1977|-1976|-1975|-1974|-1973|-1972|-1971|-1970|-1969|-1968|-1967|-1966|-1965|-1964|-1963|-1962|-1961|-1960|-1959|-1958|-1957|-1956|-1955|-1954|-1953|-1952|-1951|-1950|-1949|-1948|-1947|-1946|-1945|-1944|-1943|-1942|-1941|-1940|-1939|-1938|-1937|-1936|-1935|-1934|-1933|-1932|-1931|-1930|-1929|-1928|-1927|-1926|-1925|-1924|-1923|-1922|-1921|-1920|-1919|-1918|-1917|-1916|-1915|-1914|-1913|-1912|-1911|-1910|-1909|-1908|-1907|-1906|-1905|-1904|-1903|-1902|-1901|-1900|-1899|-1898|-1897|-1896|-1895|-1894|-1893|-1892|-1891|-1890|-1889|-1888|-1887|-1886|-1885|-1884|-1883|-1882|-1881|-1880|-1879|-1878|-1877|-1876|-1875|-1874|-1873|-1872|-1871|-1870|-1869|-1868|-1867|-1866|-1865|-1864|-1863|-1862|-1861|-1860|-1859|-1858|-1857|-1856|-1855|-1854|-1853|-1852|-1851|-1850|-1849|-1848|-1847|-1846|-1845|-1844|-1843|-1842|-1841|-1840|-1839|-1838|-1837|-1836|-1835|-1834|-1833|-1832|-1831|-1830|-1829|-1828|-1827|-1826|-1825|-1824|-1823|-1822|-1821|-1820|-1819|-1818|-1817|-1816|-1815|-1814|-1813|-1812|-1811|-1810|-1809|-1808|-1807|-1806|-1805|-1804|-1803|-1802|-1801|-1800|-1799|-1798|-1797|-1796|-1795|-1794|-1793|-1792|-1791|-1790|-1789|-1788|-1787|-1786|-1785|-1784|-1783|-1782|-1781|-1780|-1779|-1778|-1777|-1776|-1775|-1774|-1773|-1772|-1771|-1770|-1769|-1768|-1767|-1766|-1765|-1764|-1763|-1762|-1761|-1760|-1759|-1758|-1757|-1756|-1755|-1754|-1753|-1752|-1751|-1750|-1749|-1748|-1747|-1746|-1745|-1744|-1743|-1742|-1741|-1740|-1739|-1738|-1737|-1736|-1735|-1734|-1733|-1732|-1731|-1730|-1729|-1728|-1727|-1726|-1725|-1724|-1723|-1722|-1721|-1720|-1719|-1718|-1717|-1716|-1715|-1714|-1713|-1712|-1711|-1710|-1709|-1708|-1707|-1706|-1705|-1704|-1703|-1702|-1701|-1700|-1699|-1698|-1697|-1696|-1695|-1694|-1693|-1692|-1691|-1690|-1689|-1688|-1687|-1686|-1685|-1684|-1683|-1682|-1681|-1680|-1679|-1678|-1677|-1676|-1675|-1674|-1673|-1672|-1671|-1670|-1669|-1668|-1667|-1666|-1665|-1664|-1663|-1662|-1661|-1660|-1659|-1658|-1657|-1656|-1655|-1654|-1653|-1652|-1651|-1650|-1649|-1648|-1647|-1646|-1645|-1644|-1643|-1642|-1641|-1640|-1639|-1638|-1637|-1636|-1635|-1634|-1633|-1632|-1631|-1630|-1629|-1628|-1627|-1626|-1625|-1624|-1623|-1622|-1621|-1620|-1619|-1618|-1617|-1616|-1615|-1614|-1613|-1612|-1611|-1610|-1609|-1608|-1607|-1606|-1605|-1604|-1603|-1602|-1601|-1600|-1599|-1598|-1597|-1596|-1595|-1594|-1593|-1592|-1591|-1590|-1589|-1588|-1587|-1586|-1585|-1584|-1583|-1582|-1581|-1580|-1579|-1578|-1577|-1576|-1575|-1574|-1573|-1572|-1571|-1570|-1569|-1568|-1567|-1566|-1565|-1564|-1563|-1562|-1561|-1560|-1559|-1558|-1557|-1556|-1555|-1554|-1553|-1552|-1551|-1550|-1549|-1548|-1547|-1546|-1545|-1544|-1543|-1542|-1541|-1540|-1539|-1538|-1537|-1536|-1535|-1534|-1533|-1532|-1531|-1530|-1529|-1528|-1527|-1526|-1525|-1524|-1523|-1522|-1521|-1520|-1519|-1518|-1517|-1516|-1515|-1514|-1513|-1512|-1511|-1510|-1509|-1508|-1507|-1506|-1505|-1504|-1503|-1502|-1501|-1500|-1499|-1498|-1497|-1496|-1495|-1494|-1493|-1492|-1491|-1490|-1489|-1488|-1487|-1486|-1485|-1484|-1483|-1482|-1481|-1480|-1479|-1478|-1477|-1476|-1475|-1474|-1473|-1472|-1471|-1470|-1469|-1468|-1467|-1466|-1465|-1464|-1463|-1462|-1461|-1460|-1459|-1458|-1457|-1456|-1455|-1454|-1453|-1452|-1451|-1450|-1449|-1448|-1447|-1446|-1445|-1444|-1443|-1442|-1441|-1440|-1439|-1438|-1437|-1436|-1435|-1434|-1433|-1432|-1431|-1430|-1429|-1428|-1427|-1426|-1425|-1424|-1423|-1422|-1421|-1420|-1419|-1418|-1417|-1416|-1415|-1414|-1413|-1412|-1411|-1410|-1409|-1408|-1407|-1406|-1405|-1404|-1403|-1402|-1401|-1400|-1399|-1398|-1397|-1396|-1395|-1394|-1393|-1392|-1391|-1390|-1389|-1388|-1387|-1386|-1385|-1384|-1383|-1382|-1381|-1380|-1379|-1378|-1377|-1376|-1375|-1374|-1373|-1372|-1371|-1370|-1369|-1368|-1367|-1366|-1365|-1364|-1363|-1362|-1361|-1360|-1359|-1358|-1357|-1356|-1355|-1354|-1353|-1352|-1351|-1350|-1349|-1348|-1347|-1346|-1345|-1344|-1343|-1342|-1341|-1340|-1339|-1338|-1337|-1336|-1335|-1334|-1333|-1332|-1331|-1330|-1329|-1328|-1327|-1326|-1325|-1324|-1323|-1322|-1321|-1320|-1319|-1318|-1317|-1316|-1315|-1314|-1313|-1312|-1311|-1310|-1309|-1308|-1307|-1306|-1305|-1304|-1303|-1302|-1301|-1300|-1299|-1298|-1297|-1296|-1295|-1294|-1293|-1292|-1291|-1290|-1289|-1288|-1287|-1286|-1285|-1284|-1283|-1282|-1281|-1280|-1279|-1278|-1277|-1276|-1275|-1274|-1273|-1272|-1271|-1270|-1269|-1268|-1267|-1266|-1265|-1264|-1263|-1262|-1261|-1260|-1259|-1258|-1257|-1256|-1255|-1254|-1253|-1252|-1251|-1250|-1249|-1248|-1247|-1246|-1245|-1244|-1243|-1242|-1241|-1240|-1239|-1238|-1237|-1236|-1235|-1234|-1233|-1232|-1231|-1230|-1229|-1228|-1227|-1226|-1225|-1224|-1223|-1222|-1221|-1220|-1219|-1218|-1217|-1216|-1215|-1214|-1213|-1212|-1211|-1210|-1209|-1208|-1207|-1206|-1205|-1204|-1203|-1202|-1201|-1200|-1199|-1198|-1197|-1196|-1195|-1194|-1193|-1192|-1191|-1190|-1189|-1188|-1187|-1186|-1185|-1184|-1183|-1182|-1181|-1180|-1179|-1178|-1177|-1176|-1175|-1174|-1173|-1172|-1171|-1170|-1169|-1168|-1167|-1166|-1165|-1164|-1163|-1162|-1161|-1160|-1159|-1158|-1157|-1156|-1155|-1154|-1153|-1152|-1151|-1150|-1149|-1148|-1147|-1146|-1145|-1144|-1143|-1142|-1141|-1140|-1139|-1138|-1137|-1136|-1135|-1134|-1133|-1132|-1131|-1130|-1129|-1128|-1127|-1126|-1125|-1124|-1123|-1122|-1121|-1120|-1119|-1118|-1117|-1116|-1115|-1114|-1113|-1112|-1111|-1110|-1109|-1108|-1107|-1106|-1105|-1104|-1103|-1102|-1101|-1100|-1099|-1098|-1097|-1096|-1095|-1094|-1093|-1092|-1091|-1090|-1089|-1088|-1087|-1086|-1085|-1084|-1083|-1082|-1081|-1080|-1079|-1078|-1077|-1076|-1075|-1074|-1073|-1072|-1071|-1070|-1069|-1068|-1067|-1066|-1065|-1064|-1063|-1062|-1061|-1060|-1059|-1058|-1057|-1056|-1055|-1054|-1053|-1052|-1051|-1050|-1049|-1048|-1047|-1046|-1045|-1044|-1043|-1042|-1041|-1040|-1039|-1038|-1037|-1036|-1035|-1034|-1033|-1032|-1031|-1030|-1029|-1028|-1027|-1026|-1025|-1024|-1023|-1022|-1021|-1020|-1019|-1018|-1017|-1016|-1015|-1014|-1013|-1012|-1011|-1010|-1009|-1008|-1007|-1006|-1005|-1004|-1003|-1002|-1001|-1000|-999|-998|-997|-996|-995|-994|-993|-992|-991|-990|-989|-988|-987|-986|-985|-984|-983|-982|-981|-980|-979|-978|-977|-976|-975|-974|-973|-972|-971|-970|-969|-968|-967|-966|-965|-964|-963|-962|-961|-960|-959|-958|-957|-956|-955|-954|-953|-952|-951|-950|-949|-948|-947|-946|-945|-944|-943|-942|-941|-940|-939|-938|-937|-936|-935|-934|-933|-932|-931|-930|-929|-928|-927|-926|-925|-924|-923|-922|-921|-920|-919|-918|-917|-916|-915|-914|-913|-912|-911|-910|-909|-908|-907|-906|-905|-904|-903|-902|-901|-900|-899|-898|-897|-896|-895|-894|-893|-892|-891|-890|-889|-888|-887|-886|-885|-884|-883|-882|-881|-880|-879|-878|-877|-876|-875|-874|-873|-872|-871|-870|-869|-868|-867|-866|-865|-864|-863|-862|-861|-860|-859|-858|-857|-856|-855|-854|-853|-852|-851|-850|-849|-848|-847|-846|-845|-844|-843|-842|-841|-840|-839|-838|-837|-836|-835|-834|-833|-832|-831|-830|-829|-828|-827|-826|-825|-824|-823|-822|-821|-820|-819|-818|-817|-816|-815|-814|-813|-812|-811|-810|-809|-808|-807|-806|-805|-804|-803|-802|-801|-800|-799|-798|-797|-796|-795|-794|-793|-792|-791|-790|-789|-788|-787|-786|-785|-784|-783|-782|-781|-780|-779|-778|-777|-776|-775|-774|-773|-772|-771|-770|-769|-768|-767|-766|-765|-764|-763|-762|-761|-760|-759|-758|-757|-756|-755|-754|-753|-752|-751|-750|-749|-748|-747|-746|-745|-744|-743|-742|-741|-740|-739|-738|-737|-736|-735|-734|-733|-732|-731|-730|-729|-728|-727|-726|-725|-724|-723|-722|-721|-720|-719|-718|-717|-716|-715|-714|-713|-712|-711|-710|-709|-708|-707|-706|-705|-704|-703|-702|-701|-700|-699|-698|-697|-696|-695|-694|-693|-692|-691|-690|-689|-688|-687|-686|-685|-684|-683|-682|-681|-680|-679|-678|-677|-676|-675|-674|-673|-672|-671|-670|-669|-668|-667|-666|-665|-664|-663|-662|-661|-660|-659|-658|-657|-656|-655|-654|-653|-652|-651|-650|-649|-648|-647|-646|-645|-644|-643|-642|-641|-640|-639|-638|-637|-636|-635|-634|-633|-632|-631|-630|-629|-628|-627|-626|-625|-624|-623|-622|-621|-620|-619|-618|-617|-616|-615|-614|-613|-612|-611|-610|-609|-608|-607|-606|-605|-604|-603|-602|-601|-600|-599|-598|-597|-596|-595|-594|-593|-592|-591|-590|-589|-588|-587|-586|-585|-584|-583|-582|-581|-580|-579|-578|-577|-576|-575|-574|-573|-572|-571|-570|-569|-568|-567|-566|-565|-564|-563|-562|-561|-560|-559|-558|-557|-556|-555|-554|-553|-552|-551|-550|-549|-548|-547|-546|-545|-544|-543|-542|-541|-540|-539|-538|-537|-536|-535|-534|-533|-532|-531|-530|-529|-528|-527|-526|-525|-524|-523|-522|-521|-520|-519|-518|-517|-516|-515|-514|-513|-512|-511|-510|-509|-508|-507|-506|-505|-504|-503|-502|-501|-500|-499|-498|-497|-496|-495|-494|-493|-492|-491|-490|-489|-488|-487|-486|-485|-484|-483|-482|-481|-480|-479|-478|-477|-476|-475|-474|-473|-472|-471|-470|-469|-468|-467|-466|-465|-464|-463|-462|-461|-460|-459|-458|-457|-456|-455|-454|-453|-452|-451|-450|-449|-448|-447|-446|-445|-444|-443|-442|-441|-440|-439|-438|-437|-436|-435|-434|-433|-432|-431|-430|-429|-428|-427|-426|-425|-424|-423|-422|-421|-420|-419|-418|-417|-416|-415|-414|-413|-412|-411|-410|-409|-408|-407|-406|-405|-404|-403|-402|-401|-400|-399|-398|-397|-396|-395|-394|-393|-392|-391|-390|-389|-388|-387|-386|-385|-384|-383|-382|-381|-380|-379|-378|-377|-376|-375|-374|-373|-372|-371|-370|-369|-368|-367|-366|-365|-364|-363|-362|-361|-360|-359|-358|-357|-356|-355|-354|-353|-352|-351|-350|-349|-348|-347|-346|-345|-344|-343|-342|-341|-340|-339|-338|-337|-336|-335|-334|-333|-332|-331|-330|-329|-328|-327|-326|-325|-324|-323|-322|-321|-320|-319|-318|-317|-316|-315|-314|-313|-312|-311|-310|-309|-308|-307|-306|-305|-304|-303|-302|-301|-300|-299|-298|-297|-296|-295|-294|-293|-292|-291|-290|-289|-288|-287|-286|-285|-284|-283|-282|-281|-280|-279|-278|-277|-276|-275|-274|-273|-272|-271|-270|-269|-268|-267|-266|-265|-264|-263|-262|-261|-260|-259|-258|-257|-256|-255|-254|-253|-252|-251|-250|-249|-248|-247|-246|-245|-244|-243|-242|-241|-240|-239|-238|-237|-236|-235|-234|-233|-232|-231|-230|-229|-228|-227|-226|-225|-224|-223|-222|-221|-220|-219|-218|-217|-216|-215|-214|-213|-212|-211|-210|-209|-208|-207|-206|-205|-204|-203|-202|-201|-200|-199|-198|-197|-196|-195|-194|-193|-192|-191|-190|-189|-188|-187|-186|-185|-184|-183|-182|-181|-180|-179|-178|-177|-176|-175|-174|-173|-172|-171|-170|-169|-168|-167|-166|-165|-164|-163|-162|-161|-160|-159|-158|-157|-156|-155|-154|-153|-152|-151|-150|-149|-148|-147|-146|-145|-144|-143|-142|-141|-140|-139|-138|-137|-136|-135|-134|-133|-132|-131|-130|-129|-128|-127|-126|-125|-124|-123|-122|-121|-120|-119|-118|-117|-116|-115|-114|-113|-112|-111|-110|-109|-108|-107|-106|-105|-104|-103|-102|-101|-100|-99|-98|-97|-96|-95|-94|-93|-92|-91|-90|-89|-88|-87|-86|-85|-84|-83|-82|-81|-80|-79|-78|-77|-76|-75|-74|-73|-72|-71|-70|-69|-68|-67|-66|-65|-64|-63|-62|-61|-60|-59|-58|-57|-56|-55|-54|-53|-52|-51|-50|-49|-48|-47|-46|-45|-44|-43|-42|-41|-40|-39|-38|-37|-36|-35|-34|-33|-32|-31|-30|-29|-28|-27|-26|-25|-24|-23|-22|-21|-20|-19|-18|-17|-16|-15|-14|-13|-12|-11|-10|-9|-8|-7|-6|-5|-4|-3|-2|-1|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255|256|257|258|259|260|261|262|263|264|265|266|267|268|269|270|271|272|273|274|275|276|277|278|279|280|281|282|283|284|285|286|287|288|289|290|291|292|293|294|295|296|297|298|299|300|301|302|303|304|305|306|307|308|309|310|311|312|313|314|315|316|317|318|319|320|321|322|323|324|325|326|327|328|329|330|331|332|333|334|335|336|337|338|339|340|341|342|343|344|345|346|347|348|349|350|351|352|353|354|355|356|357|358|359|360|361|362|363|364|365|366|367|368|369|370|371|372|373|374|375|376|377|378|379|380|381|382|383|384|385|386|387|388|389|390|391|392|393|394|395|396|397|398|399|400|401|402|403|404|405|406|407|408|409|410|411|412|413|414|415|416|417|418|419|420|421|422|423|424|425|426|427|428|429|430|431|432|433|434|435|436|437|438|439|440|441|442|443|444|445|446|447|448|449|450|451|452|453|454|455|456|457|458|459|460|461|462|463|464|465|466|467|468|469|470|471|472|473|474|475|476|477|478|479|480|481|482|483|484|485|486|487|488|489|490|491|492|493|494|495|496|497|498|499|500|501|502|503|504|505|506|507|508|509|510|511|512|513|514|515|516|517|518|519|520|521|522|523|524|525|526|527|528|529|530|531|532|533|534|535|536|537|538|539|540|541|542|543|544|545|546|547|548|549|550|551|552|553|554|555|556|557|558|559|560|561|562|563|564|565|566|567|568|569|570|571|572|573|574|575|576|577|578|579|580|581|582|583|584|585|586|587|588|589|590|591|592|593|594|595|596|597|598|599|600|601|602|603|604|605|606|607|608|609|610|611|612|613|614|615|616|617|618|619|620|621|622|623|624|625|626|627|628|629|630|631|632|633|634|635|636|637|638|639|640|641|642|643|644|645|646|647|648|649|650|651|652|653|654|655|656|657|658|659|660|661|662|663|664|665|666|667|668|669|670|671|672|673|674|675|676|677|678|679|680|681|682|683|684|685|686|687|688|689|690|691|692|693|694|695|696|697|698|699|700|701|702|703|704|705|706|707|708|709|710|711|712|713|714|715|716|717|718|719|720|721|722|723|724|725|726|727|728|729|730|731|732|733|734|735|736|737|738|739|740|741|742|743|744|745|746|747|748|749|750|751|752|753|754|755|756|757|758|759|760|761|762|763|764|765|766|767|768|769|770|771|772|773|774|775|776|777|778|779|780|781|782|783|784|785|786|787|788|789|790|791|792|793|794|795|796|797|798|799|800|801|802|803|804|805|806|807|808|809|810|811|812|813|814|815|816|817|818|819|820|821|822|823|824|825|826|827|828|829|830|831|832|833|834|835|836|837|838|839|840|841|842|843|844|845|846|847|848|849|850|851|852|853|854|855|856|857|858|859|860|861|862|863|864|865|866|867|868|869|870|871|872|873|874|875|876|877|878|879|880|881|882|883|884|885|886|887|888|889|890|891|892|893|894|895|896|897|898|899|900|901|902|903|904|905|906|907|908|909|910|911|912|913|914|915|916|917|918|919|920|921|922|923|924|925|926|927|928|929|930|931|932|933|934|935|936|937|938|939|940|941|942|943|944|945|946|947|948|949|950|951|952|953|954|955|956|957|958|959|960|961|962|963|964|965|966|967|968|969|970|971|972|973|974|975|976|977|978|979|980|981|982|983|984|985|986|987|988|989|990|991|992|993|994|995|996|997|998|999|1000|1001|1002|1003|1004|1005|1006|1007|1008|1009|1010|1011|1012|1013|1014|1015|1016|1017|1018|1019|1020|1021|1022|1023|1024|1025|1026|1027|1028|1029|1030|1031|1032|1033|1034|1035|1036|1037|1038|1039|1040|1041|1042|1043|1044|1045|1046|1047|1048|1049|1050|1051|1052|1053|1054|1055|1056|1057|1058|1059|1060|1061|1062|1063|1064|1065|1066|1067|1068|1069|1070|1071|1072|1073|1074|1075|1076|1077|1078|1079|1080|1081|1082|1083|1084|1085|1086|1087|1088|1089|1090|1091|1092|1093|1094|1095|1096|1097|1098|1099|1100|1101|1102|1103|1104|1105|1106|1107|1108|1109|1110|1111|1112|1113|1114|1115|1116|1117|1118|1119|1120|1121|1122|1123|1124|1125|1126|1127|1128|1129|1130|1131|1132|1133|1134|1135|1136|1137|1138|1139|1140|1141|1142|1143|1144|1145|1146|1147|1148|1149|1150|1151|1152|1153|1154|1155|1156|1157|1158|1159|1160|1161|1162|1163|1164|1165|1166|1167|1168|1169|1170|1171|1172|1173|1174|1175|1176|1177|1178|1179|1180|1181|1182|1183|1184|1185|1186|1187|1188|1189|1190|1191|1192|1193|1194|1195|1196|1197|1198|1199|1200|1201|1202|1203|1204|1205|1206|1207|1208|1209|1210|1211|1212|1213|1214|1215|1216|1217|1218|1219|1220|1221|1222|1223|1224|1225|1226|1227|1228|1229|1230|1231|1232|1233|1234|1235|1236|1237|1238|1239|1240|1241|1242|1243|1244|1245|1246|1247|1248|1249|1250|1251|1252|1253|1254|1255|1256|1257|1258|1259|1260|1261|1262|1263|1264|1265|1266|1267|1268|1269|1270|1271|1272|1273|1274|1275|1276|1277|1278|1279|1280|1281|1282|1283|1284|1285|1286|1287|1288|1289|1290|1291|1292|1293|1294|1295|1296|1297|1298|1299|1300|1301|1302|1303|1304|1305|1306|1307|1308|1309|1310|1311|1312|1313|1314|1315|1316|1317|1318|1319|1320|1321|1322|1323|1324|1325|1326|1327|1328|1329|1330|1331|1332|1333|1334|1335|1336|1337|1338|1339|1340|1341|1342|1343|1344|1345|1346|1347|1348|1349|1350|1351|1352|1353|1354|1355|1356|1357|1358|1359|1360|1361|1362|1363|1364|1365|1366|1367|1368|1369|1370|1371|1372|1373|1374|1375|1376|1377|1378|1379|1380|1381|1382|1383|1384|1385|1386|1387|1388|1389|1390|1391|1392|1393|1394|1395|1396|1397|1398|1399|1400|1401|1402|1403|1404|1405|1406|1407|1408|1409|1410|1411|1412|1413|1414|1415|1416|1417|1418|1419|1420|1421|1422|1423|1424|1425|1426|1427|1428|1429|1430|1431|1432|1433|1434|1435|1436|1437|1438|1439|1440|1441|1442|1443|1444|1445|1446|1447|1448|1449|1450|1451|1452|1453|1454|1455|1456|1457|1458|1459|1460|1461|1462|1463|1464|1465|1466|1467|1468|1469|1470|1471|1472|1473|1474|1475|1476|1477|1478|1479|1480|1481|1482|1483|1484|1485|1486|1487|1488|1489|1490|1491|1492|1493|1494|1495|1496|1497|1498|1499|1500|1501|1502|1503|1504|1505|1506|1507|1508|1509|1510|1511|1512|1513|1514|1515|1516|1517|1518|1519|1520|1521|1522|1523|1524|1525|1526|1527|1528|1529|1530|1531|1532|1533|1534|1535|1536|1537|1538|1539|1540|1541|1542|1543|1544|1545|1546|1547|1548|1549|1550|1551|1552|1553|1554|1555|1556|1557|1558|1559|1560|1561|1562|1563|1564|1565|1566|1567|1568|1569|1570|1571|1572|1573|1574|1575|1576|1577|1578|1579|1580|1581|1582|1583|1584|1585|1586|1587|1588|1589|1590|1591|1592|1593|1594|1595|1596|1597|1598|1599|1600|1601|1602|1603|1604|1605|1606|1607|1608|1609|1610|1611|1612|1613|1614|1615|1616|1617|1618|1619|1620|1621|1622|1623|1624|1625|1626|1627|1628|1629|1630|1631|1632|1633|1634|1635|1636|1637|1638|1639|1640|1641|1642|1643|1644|1645|1646|1647|1648|1649|1650|1651|1652|1653|1654|1655|1656|1657|1658|1659|1660|1661|1662|1663|1664|1665|1666|1667|1668|1669|1670|1671|1672|1673|1674|1675|1676|1677|1678|1679|1680|1681|1682|1683|1684|1685|1686|1687|1688|1689|1690|1691|1692|1693|1694|1695|1696|1697|1698|1699|1700|1701|1702|1703|1704|1705|1706|1707|1708|1709|1710|1711|1712|1713|1714|1715|1716|1717|1718|1719|1720|1721|1722|1723|1724|1725|1726|1727|1728|1729|1730|1731|1732|1733|1734|1735|1736|1737|1738|1739|1740|1741|1742|1743|1744|1745|1746|1747|1748|1749|1750|1751|1752|1753|1754|1755|1756|1757|1758|1759|1760|1761|1762|1763|1764|1765|1766|1767|1768|1769|1770|1771|1772|1773|1774|1775|1776|1777|1778|1779|1780|1781|1782|1783|1784|1785|1786|1787|1788|1789|1790|1791|1792|1793|1794|1795|1796|1797|1798|1799|1800|1801|1802|1803|1804|1805|1806|1807|1808|1809|1810|1811|1812|1813|1814|1815|1816|1817|1818|1819|1820|1821|1822|1823|1824|1825|1826|1827|1828|1829|1830|1831|1832|1833|1834|1835|1836|1837|1838|1839|1840|1841|1842|1843|1844|1845|1846|1847|1848|1849|1850|1851|1852|1853|1854|1855|1856|1857|1858|1859|1860|1861|1862|1863|1864|1865|1866|1867|1868|1869|1870|1871|1872|1873|1874|1875|1876|1877|1878|1879|1880|1881|1882|1883|1884|1885|1886|1887|1888|1889|1890|1891|1892|1893|1894|1895|1896|1897|1898|1899|1900|1901|1902|1903|1904|1905|1906|1907|1908|1909|1910|1911|1912|1913|1914|1915|1916|1917|1918|1919|1920|1921|1922|1923|1924|1925|1926|1927|1928|1929|1930|1931|1932|1933|1934|1935|1936|1937|1938|1939|1940|1941|1942|1943|1944|1945|1946|1947|1948|1949|1950|1951|1952|1953|1954|1955|1956|1957|1958|1959|1960|1961|1962|1963|1964|1965|1966|1967|1968|1969|1970|1971|1972|1973|1974|1975|1976|1977|1978|1979|1980|1981|1982|1983|1984|1985|1986|1987|1988|1989|1990|1991|1992|1993|1994|1995|1996|1997|1998|1999|2000|2001|2002|2003|2004|2005|2006|2007|2008|2009|2010|2011|2012|2013|2014|2015|2016|2017|2018|2019|2020|2021|2022|2023|2024|2025|2026|2027|2028|2029|2030|2031|2032|2033|2034|2035|2036|2037|2038|2039|2040|2041|2042|2043|2044|2045|2046|2047|2048|2049|2050|2051|2052|2053|2054|2055)\b


这么多答案,但没有人在评论中读到(或关心)有关作战方面的问题?

I'm writing an interpreter in OCaml .... how can i validate the input
number within the range without using regex ?? – Trung Nguyen Mar 2
at 17:30

正如许多正确的答案所指出的那样,在这种情况下使用regex是可怕的,让我们考虑一下ocaml中的其他方法吧!我用ocaml已经有一段时间了,但是通过查找一些构造,我可以将其组合起来:

1
2
3
4
5
6
7
8
9
10
11
12
let isInRange i =
    not(i < -2055 or i > 2055);;

let isIntAndInRange s =
    try
    let i = int_of_string s in
    not(i < -2055 or i > 2055)
    with Failure"int_of_string" -> false;;

let () = print_string"type a number:" in
let s = read_line () in
isIntAndInRange s

如果有任何不清楚的地方,请阅读它的语法、类型转换函数、异常处理和输入输出函数。

用户输入部分仅用于演示。在那里使用read_int函数可能更方便。但是处理异常的基本概念保持不变。


分析问题

如果您"必须"使用regex,请通过分析接受的排列来分解问题。

"从-2055到2055的范围"可以表示为:

  • 可选的
  • 可选前导零
  • 后面是一个0到2055之间的数字

"从0到2055的数字"可以是有限数量的特定排列之一:

  • 一位数(0~9)
  • 两位数(10-99)
  • 三位数(100-999)
  • 以1开头的四位数(1000-1999)
  • 以20开头的四位数(2000-204*9)
  • 从205(2050-2055)开始的四位数

请注意,在这个regex中,不需要区分范围"0-9"和"1-9",只有最后两个范围对接受的数字/字符的范围有任何限制(用星号表示)。

编写组件regex表达式

上述每个组成部分都很容易单独表示为正则表达式:

  • -?
  • 0**
    • [0-9]
    • [0-9] [0-9]
    • [09] [09] [0-9]
    • 1[0-9][0-9][0-9]
    • 20 [04-] [0-9]
    • 205〔0—5〕

把表达式放在一起

整个比赛的相关表达式为:

1
-?0*([0-9]|[0-9][0-9]|[0-9][0-9][0-9]|1[0-9][0-9][0-9]|20[0-4][0-9]|205[0-5])

或者更简明扼要地说:

1
-?0*([0-9]{1,3}|1[0-9]{3}|20[0-4][0-9]|205[0-5])

假设输入只包含"数字"而没有其他内容,那么最终的regex是:

1
^-?0*([0-9]{1,3}|1[0-9]{3}|20[0-4][0-9]|205[0-5])$

如果有必要允许使用前导加号,则这将变为:

1
^[-+]?0*([0-9]{1,3}|1[0-9]{3}|20[0-4][0-9]|205[0-5])$

下面是一个JS小提琴,演示了最后一个regex的传递和失败。


作为AliteralMind提供的伟大表达的另一种方法,这里有一种更长但有趣的方法,以了解另一种方法可能是什么样子(以及不做什么)。

这是一个有趣的练习,因为你可以想到两种不同的方法:大致上,你可以:

  • 继续匹配4个字符的数字,然后匹配3个字符的数字,等等。
  • 或者通过匹配千位,然后匹配百位等继续。
  • 不尝试,你怎么知道哪一个最好?结果证明,第一种方法(aliteralmind的答案)更经济。

    下面,我用PHP语言包含了一系列测试,以防您或其他人想要检查输出。

    下面,我将以"自由间距模式"为您提供regex,它允许在regex中添加注释,这样您就可以轻松理解它的作用。然而,并不是所有的regex引擎都支持自由间距模式,所以在我们开始讨论有趣的部分之前,这里将regex作为一个单行程序。

    请注意,您的问题提到了从-2055到2055的数字。我假设你想匹配"正常数字",不带前导零。这意味着regex将匹配999而不是0999。如果你想要前导零,让我知道,这是一个非常容易的调整。

    另外,如果您在UTF-8模式下进行匹配,那么应该用[0-9]替换\d。这是更常见的形式。

    作为一个一行的regex

    1
    ^(?!-0$)-?(?:(?=\d{4}$)[12])?(?:(?=\d{3}$)(?:(?:(?<=^)|(?<=^-)|(?<=1)|(?<=-1))\d|(?:(?<=2)|(?<=-2))0))?(?:(?=\d{2}$)(?:(?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|(?<=^\d{2})(?<!20)|(?<=^-\d{2})(?<!-20))\d|(?:(?<=20)|(?<=-20))[0-5]))?(?:(?=\d$)(?:(?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|(?<=^\d{2})|(?<=^-\d{2})|(?<=^\d{3})(?<!205)|(?<=^-\d{3})(?<!-205))\d|(?:(?<=205)|(?<=-205))[0-5]))$

    自由间距模式下的正则表达式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    (?x)                # free-spacing mode
    ^                   # anchor at beginning of string.
    (?!-0$)-?           # optional minus sign, but not for -0

    (?:                 # OPTIONAL THOUSANDS DIGIT
    (?=\d{4}$)[12]      # assert that the number is 4-digit long, match 1 or 2
    )?                  # end optional thousands digit


    (?:                 # OPTIONAL HUNDREDS DIGIT
    (?=\d{3}$)          # assert that there are three digits left
    (?:                 # non-capturing group
      (?:(?<=^)|(?<=^-)|(?<=1)|(?<=-1))\d    # if preceding chars are 1, -1 or head of string: value can be any digit
      |                      # or
      (?:(?<=2)|(?<=-2))0                # if preceding chars are 2 or -2: value must be 0
    )                   # close non-capturing group
    )?                  # end optional hundreds digits

    (?:             # OPTIONAL TENS DIGIT
    (?=\d{2}$)      # assert that there are two digits left
    (?:             # start non-capturing group

                    # if preceding char is head of string, single digit,
                    # or two digits that are not 20
                    # (with or without a minus)
                    # value can be any digit
      (?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|
         (?<=^\d{2})(?<!20)|(?<=^-\d{2})(?<!-20))\d  
    |               # or
    (?:(?<=20)|(?<=-20))[0-5]  # if preceding chars are 20 or -20: value can be from 0 to 5

    )               # end non-capturing group
    )?              # close optional tens digits

    (?:             # FINAL DIGIT (non optional)
    (?=\d$)         # assert that there is only one digit left
    (?:             # start non-capturing group

                    # if preceding char is head of string, single digit,
                    # two digits, or three digits that are not 205
                    # (with or without a minus)
                    # value can be any digit
      (?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|
          (?<=^\d{2})|(?<=^-\d{2})|
          (?<=^\d{3})(?<!205)|(?<=^-\d{3})(?<!-205))
          \d
      |             # or
      (?:(?<=205)|(?<=-205))[0-5] # if preceding chars are 205 or -205: value can be from 0 to 5
    )               # end non-capturing group
    )               # end final digit
    $

    系列试验

    这些测试试图与-100000到100000的数字相匹配。它们产生以下输出:

    1
    2
    3
    Successful test: matches from -2055 to 2055
    Successful test: NO matches from -100000 to -2056
    Successful test: NO matches from 2056 to 100000

    代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <?php
    $regex="~^(?!-0$)-?(?:(?=\d{4}$)[12])?(?:(?=\d{3}$)(?:(?:(?<=^)|(?<=^-)|(?<=1)|(?<=-1))\d|(?:(?<=2)|(?<=-2))0))?(?:(?=\d{2}$)(?:(?:(?<=20)|(?<=-20))[0-5]|(?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|(?<=^\d{2})(?<!20)|(?<=^-\d{2})(?<!-20))\d))?(?:(?=\d$)(?:(?:(?<=205)|(?<=-205))[0-5]|(?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|(?<=^\d{2})|(?<=^-\d{2})|(?<=^\d{3})(?<!205)|(?<=^-\d{3})(?<!-205))\d))$~";

    // Test 1
    $success="Successful test: matches from -2055 to 2055";
    for($i=-2055;$i<=2055;$i++) {
    $chari = sprintf("%d",$i);
    if (! preg_match($regex,$chari)) {
        $success="Failed test: matches from -2055 to 2055";
        echo $chari.": No Match!<br />";
        }
    }
    echo $success."<br />";

    // Test 2
    $success="Successful test: NO matches from -100000 to -2056";
    for($i=-100000;$i<=-2056;$i++) {
    $chari = sprintf("%d",$i);
    if (preg_match($regex,$chari)) {
        $success="Failed test: NO matches from -100000 to -2056";
        echo $chari.": Match!<br />";
        }
    }
    echo $success."<br />";

    // Test 3
    $success="Successful test: NO matches from 2056 to 100000";
    for($i=2056;$i<=100000;$i++) {
    $chari = sprintf("%d",$i);
    if (preg_match($regex,$chari)) {
        $success="Failed test: NO matches from 2056 to 100000";
        echo $chari.": Match!<br />";
        }
    }
    echo $success."<br />";

    ?>

    速度测试

    这是我的简单速度测试的输出,匹配范围从-1米到+1米。正如Casimir指出的,如果AliteralMind的表达式被锚定,而不是变慢,它将更快25%!

    1
    2
    3
    zx81: 3.796217918396
    aliteralmind: 3.9922280311584
    difference: 5.1632998151294 percent longer

    测试代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $regex="~(?x)^(?!-0$)-?(?:(?=\d{4}$)[12])?(?:(?=\d{3}$)(?:(?:(?<=^)|(?<=^-)|(?<=1)|(?<=-1))\d|(?:(?<=2)|(?<=-2))0))?(?:(?=\d{2}$)(?:(?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|(?<=^\d{2})(?<!20)|(?<=^-\d{2})(?<!-20))\d|(?:(?<=20)|(?<=-20))[0-5]))?(?:(?=\d$)(?:(?:(?<=^)|(?<=^-)|(?<=^\d)|(?<=^-\d)|(?<=^\d{2})|(?<=^-\d{2})|(?<=^\d{3})(?<!205)|(?<=^-\d{3})(?<!-205))\d|(?:(?<=205)|(?<=-205))[0-5]))$~";

    $regex2 ="~(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2}|(?<!-)0+))\b~";

    $start=microtime(TRUE);
    for ($i=-1000000;$i<1000000;$i++) preg_match($regex,$i);
    $zxend=microtime(TRUE);
    for ($i=-1000000;$i<1000000;$i++) preg_match($regex2,$i);
    $alitend=microtime(TRUE);
    $zx81 = $zxend-$start;
    $alit = $alitend-$zxend;
    $diff = 100*($alit-$zx81)/$zx81;
    echo"zx81:".$zx81."<br />";
    echo"aliteralmind:".$alit."<br />";
    echo"difference:".$diff." percent longer<br />";


    为什么只用regex来检查数字?

    1
    2
    3
    4
    5
    6
    int n = -2000;

    if(n >= -2055 && n <= 2055)
    //Do something
    else
    //Do something else


    看看这个伟大的工具,它为数值范围生成一个regex:

    http://gamon.web派别.com/regexnumericrangegenerator/

    对于OP请求的范围,它生成:-?([0-9]{1,3}|1[0-9]{3}|20[0-4][0-9]|205[0-5])


    试试这个:

    1
    \-?\b0*(205[0-5]|20[0-4]\d|1?\d{3}|\d{1,2})\b


    尝试使用一个非常简单的regex。

    1
    ^([-0][0-1][0-9][0-9][0-9])$|^([-0]20[0-4][0-9])$|^([-0]205[0-5])$

    视觉表现

    enter image description here

    这很容易理解。

    • 第1组[-0][0-1][0-9][0-9][0-9]将涵盖[-1999、1999]值。
    • 第2组[-0]20[0-4][0-9]将包括[-2000,-2049]和[2000,2049]值。
    • 第3组[-0]205[0-5]将包括[-2050,-2050]和[2050,2055]值。

    String.format("%05d", number) is doing very well done job here?

    示例代码:(为了更清楚起见,请阅读内联注释。)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    int[] numbers = new int[] { -10002, -3000, -2056, -2055, -2000, -1999, -20,
                                -1,  0, 1, 260, 1999, 2000, 2046, 2055, 2056, 2955,
                                 3000, 10002, 123456 };

    //valid range -2055 to 2055 inclusive

    Pattern p = Pattern.compile("^([-0][0-1][0-9][0-9][0-9])$|^([-0]20[0-4][0-9])$|^([-0]205[0-5])$");

    for (int number : numbers) {
        String string = String.format("%05d", number);
        Matcher m = p.matcher(string);

        if (m.find()) {
            System.out.println(number +" is in range.");
        } else {
            System.out.println(number +" is not in range.");
        }
    }

    输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    -10002 is not in range.
    -3000 is not in range.
    -2056 is not in range.
    -2055 is in range.
    -2000 is in range.
    -1999 is in range.
    -20 is in range.
    -1 is in range.
    0 is in range.
    1 is in range.
    260 is in range.
    1999 is in range.
    2000 is in range.
    2046 is in range.
    2055 is in range.
    2056 is not in range.
    2955 is not in range.
    3000 is not in range.
    10002 is not in range.
    123456 is not in range.


    又一个——

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     #  ^-?0*(?:20(?:[0-4][0-9]|5[0-5])|[0-9]{1,3})$

     ^
     -?
     0*
     (?:
          20
          (?:
               [0-4] [0-9]
            |  
               5 [0-5]
          )
       |  
          [0-9]{1,3}
     )
     $

    试试这个:

    1
    ^-?0*(1?[0-9]{1,3}|20[0-4][0-9]|205[0-5])$

    括号前的regex与可选的-和任何前导0匹配。

    括号(1?[0-9]{1,3}中的第一部分)与0-1999匹配。

    括号(20[0-4][0-9]中的第二部分与2000-2049匹配。

    括号(205[0-5]中的第三部分与2050-2055匹配。