/ Extrakcia párov slov pomocou String.split () - java, regex, string, split

Extrakcia párov slov pomocou String.split () - java, regex, string, split

Vzhľadom na to:

String input = "one two three four five six seven";

Existuje regex, ktorý pracuje s String.split() chytiť (až) dve slová naraz, aby:

String[] pairs = input.split("some regex");
System.out.println(Arrays.toString(pairs));

výsledky v tomto:

[one two, three four, five six, seven]

Táto otázka je o rozdelený regulárny výraz, to je nie o riešení „nájsť riešenie“ alebo o iných „spôsoboch, ako to funguje iným spôsobom“.

odpovede:

77 pre odpoveď č. 1

V súčasnosti (vrátane Java 8) je to možné split(), ale v reálnom svete tento prístup nepoužívajte, pretože to vyzerá, že je založené na chybe (pozeranie v Java by malo mať zrejmú maximálnu dĺžku, ale toto riešenie používa w+ ktoré toto obmedzenie nerešpektuje). Namiesto toho použite Pattern a Matcher triedy, aby sa predišlo nadmernej komplikácii tenkých a udržiavacích pekiel, pretože toto správanie sa môže meniť v ďalších verziách Java alebo v prostrediach podobných Java, ako je Android.


Je to to, čo hľadáte?
(môžete nahradiť \w s \S zahrnúť všetky medzery, ale v tomto príklade odídem \w pretože je ľahšie prečítať pomocou regulárneho výrazu \w\s potom \S\s)

String input = "one two three four five six seven";
String[] pairs = input.split("(?<!\G\w+)\s");
System.out.println(Arrays.toString(pairs));

výkon:

[one two, three four, five six, seven]

G je predchádzajúci zápas, (?<!regex) je negatívny pohľad.

v split snažíme sa

  1. nájsť priestory -> \s
  2. ktoré nie sú predpovedané -> (?<!negativeLookBehind)
  3. nejakým slovom -> \w+
  4. s predtým priradeným (medzerník) -> \G
  5. pred tým ->\G\w+.

Len zmätok, ktorý som mal na začiatku, bolo, ako by to fungovalo pre prvý priestor, pretože chceme, aby sa tento priestor ignoroval. Dôležitá informácia je, že \G na začiatku zápasu začiatok reťazca ^.

Takže pred prvou iteráciou bude regex v negatívnom pohľade vyzerať (?<!^\w+) a od prvého miesta robiť mať ^\w+ predtým to nemôže byť zhodné s rozdelením. Ďalší priestor tento problém nebude mať, takže bude porovnaný a informácie o ňom (napríklad jeho pozície v input String) budú uložené v \G a použité neskôr v ďalšom negatívnom pohľade.

Takže pre 3. miesto regulárny výraz skontroluje, či existuje predtým priradený priestor \G a slovo \w+ pred tým. Pretože výsledok tohto testu bude pozitívny, negatívny pohľad ho nebude akceptovať, takže tento priestor nebude uzavretý, ale 4. priestor tento problém nebude mať, pretože priestor pred tým nebude rovnaký, ako je uložený v \G (bude mať inú pozíciu v input String).


Tiež, ak by niekto chcel oddeliť na povedzme každý tretí priestor, môžete použiť tento formulár (na základe @maybeWeCouldStealAVan"s odpoveď ktorý bol odstránený, keď som uverejnil tento fragment odpovede)

input.split("(?<=\G\w{1,100}\s\w{1,100}\s\w{1,100})\s")

Namiesto 100 môžete použiť nejakú väčšiu hodnotu, ktorá bude aspoň veľkosť dĺžky najdlhšieho slova v reťazci.


Len som si všimol, že môžeme tiež použiť + namiesto {1,maxWordLength} ak sa chceme rozdeliť na každé nepárne číslo, napríklad každé 3., 5., 7.

String data = "0,0,1,2,4,5,3,4,6,1,3,3,4,5,1,1";
String[] array = data.split("(?<=\G\d+,\d+,\d+,\d+,\d+),");//every 5th comma

8 pre odpoveď č. 2

Bude to fungovať, ale maximálna dĺžka slova musí byť stanovená vopred:

String input = "one two three four five six seven eight nine ten eleven";
String[] pairs = input.split("(?<=\G\S{1,30}\s\S{1,30})\s");
System.out.println(Arrays.toString(pairs));

Páči sa mi, že odpoveď spoločnosti Pshemo je lepšia, je kratšia a použiteľná na ľubovoľných dĺžkach slov, ale to (ako zdôraznil @ Shemo) má tú výhodu, že sa dá prispôsobiť skupinám s viac ako 2 slovami.


0 pre odpoveď č. 3

to fungovalo pre mňa (w+s*){2}Ks príklad tu

  • požadované slovo, za ktorým nasleduje medzera (w+s*)
  • opakuje sa dvakrát {2}
  • ignorovať predtým priradené znaky K
  • požadovaný priestor s

-1 pre odpoveď č. 4

Môžete to vyskúšať:

[a-z]+s[a-z]+

Aktualizované:

([a-z]+s[a-z]+)|[a-z]+

tu zadajte popis obrázku

Aktualizované:

 String pattern = "([a-z]+\s[a-z]+)|[a-z]+";
String input = "one two three four five six seven";

Pattern splitter = Pattern.compile(pattern);
String[] results = splitter.split(input);

for (String pair : results) {
System.out.println("Output = "" + pair + """);