2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Säännöllisissä lausekkeissa,? Se voi edustaa määrää, 0 tai 1 kertaa, mikä vastaa arvoa 0, 1}, tai sitä voidaan käyttää erikoismerkkinä edustamaan muita merkityksiä.
?, jota seuraa muut määrän tarkenteet, tarkoittaa ei-ahnetta hakua, toisin sanoen vastaavuutta lyhimmän mahdollisen merkkijonon kanssa.
Katsotaanpa esimerkkiä:
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("a.*?");
- Matcher matcher = pattern.matcher("abcabc");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- }
- }
Tulos suoritus suorituksen jälkeen: abcabc
Eikö se ole lyhin ottelu? Miksi se epäonnistui?
Tämä sisältää itse asiassa ei-ahneen vastaavuuden säännöt:Ei-ahneessa sovituksessa lyhin polku sovitetaan ennen seuraavaa sääntöä. Jos seuraavaa sääntöä ei ole, se käsitellään ahneeksi sovitukseksi.
Toisin sanoen, jos vain "a.*?", se käsitellään silti ahneen vastaavuuden mukaan.
Katsotaanpa oikeaa käyttöä:
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("(a.*?)(.*)");
- Matcher matcher = pattern.matcher("afcafc");
- if (matcher.matches()) {
- System.out.println(matcher.group(0));
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2));
- }
- }
Tulos suoritus suorituksen jälkeen:
- afcafc
- a
- fcafc
Kuten näet, ensimmäinen sieppausryhmä kaappaa lyhimmän merkkijonon "a" ja toinen sieppausryhmä kaappaa "fcafc".
Katsotaanpa kahta muuta tilannetta:
Sieppausryhmässä käytettynä ?: sijoitetaan ennen säännöllistä lauseketta osoittamaan täsmäämistä, mutta ei kaappausta, eli tätä yhteensopivien arvojen ryhmää ei voida saada ryhmämenetelmällä.
Katsotaanpa esimerkkiä
- @Test
- public void test0() {
- Pattern pattern = Pattern.compile("\d{4}-(?:[a-z]+)");
- Matcher matcher = pattern.matcher("3214-opo");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1)); // 报错
- }
- }
Virhe raportoidaan kaapattaessa ryhmän(1) kautta, eli se voidaan sovittaa, mutta sitä ei voi siepata. Jos ?: poistetaan, se voidaan kaapata normaalisti ryhmän (1) kautta.
(?s) ottaa käyttöön yksirivisen tilan oikealla puolella, mikä vastaa mitä tahansa merkkiä, myös rivinvaihtomerkkiä n.
Katsotaanpa esimerkkiä:
- private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)";
-
-
- /**
- * 从输出结果可知,匹配到了换行符 'n'
- */
- @Test
- public void test4() {
- Pattern pattern = Pattern.compile(DEFAULT_VARIABLE_PATTERN);
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2)); // (?s) 不能作为捕获组,报错
- }
- }
Sieppauksen aikana (?s) ei voi kaapata kaappausryhmänä, joten "(?s).*)" voi kaapata enintään ryhmän(1), ja ryhmä(2) kaapattaessa raportoidaan virhe.
- @Test
- public void test5() {
- Pattern pattern = Pattern.compile("(.*)");
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- }
- }
Kun olet poistanut (?s), yritä sovittaa "abcnsdf", koska rivinvaihtomerkkiä ei voida suorittaa loppuun, joten mitään ei tulosteta.